集团网站建设新闻,东莞建网站找哪里,网页版梦幻西游周游方壶,海尔网站建设1000亿级存储、30W级qps系统如何架构#xff1f;来一个天花板案例
说在前面
在尼恩的#xff08;50#xff09;读者社群中#xff0c;经常遇到一个 非常、非常高频的一个架构面试题#xff0c;类似如下#xff1a; 千万级数据#xff0c;如何做系统架构#xff1f;亿…1000亿级存储、30W级qps系统如何架构来一个天花板案例
说在前面
在尼恩的50读者社群中经常遇到一个 非常、非常高频的一个架构面试题类似如下 千万级数据如何做系统架构亿级数据如何做做系统架构千万级流量如何做系统架构亿级流量如何做做系统架构高并发系统如何架构 **最近有个小伙伴阿里三面又遇到了这个问题。**这类问题非常复杂稍微回答不好面试就挂掉。
尼恩一直想梳理一个教科书式的答案。
这里尼恩结合B站的行业案例《B站千亿级点赞系统服务架构设计》从 面试维度对这个方案进行二次重构和梳理然后把梳理的结果作为以上面试题的参考答案并收入咱们的《尼恩Java面试宝典 PDF》 V54版本供后面的小伙伴参考大家一定好好看看这个教科书级别的答案。
原始方案的作者是芦文超是哔哩哔哩资深开发工程师。原始的文章请参见b站的公众号 pdf版收藏在尼恩的3高行业案例集合中也可以找尼恩获取。
下面的内容并不是原文而是尼恩是结合自己的3高架构笔记以及尼恩的3高架构知识体系3高架构宇宙做的二次创作。 注本文以 PDF 持续更新最新尼恩 架构笔记、面试题 的PDF文件请从这里获取码云 点赞场景的业务分析
做系统架构首先要需求分析。
点赞的业务已经足够的简单极致的简要
需求1视频的点赞数 需求2UP主维度的总获赞数 需求3个人的点赞记录 需求N细分的需求比较多…
大家自行脑补当然也可以来尼恩的技术自由社群 50里边交流。
数据规模、流量规模分析
做系统架构其次要确定 数据规模、流量规模 为啥呢
不同的体量架构的方式、方法、方案都完全不一样。
按照尼恩的3高架构笔记中的分析套路接下来对这个案例的数据规模、流量规模进行 梳理和分析。
数据规模千亿级别
流量规模
读流量30W QPS 全站点赞状态查询、点赞数查询等【读流量】超过300k
写流量1.5W QPS 点赞、点踩等【写流量】超过15K 大流量、大数据场景下点赞中台化诉求
点赞功能在中台化之前是分散的。各大业务模块都有点赞功能的存在如以下模块
稿件、视频、动态、专栏、评论、弹幕、等等 以 “稿件” 为例点赞服务需要提供
对某个稿件点赞取消点赞、点踩取消点踩查询是否对 单个 或者 一批稿件 点过赞踩 - 即点赞状态查询查询某个稿件的点赞数查询某个用户的点赞列表查询某个稿件的点赞人列表查询用户收到的总点赞数
大流量、大数据场景下需要进行中台化、平台化
进行业务聚合提供多种实体维度数据查询、数据分析的能力点赞作为一个与社区实体共存的服务需要提供很强的容灾能力提供业务快速接入的能力配置级别数据存储上缓存、DB具备数据隔离存储的能力多租户
中台化 之后的架构图如下 从此各大业务模块业务子系统再也不用担心点赞的 海量数据问题 巨量的流量问题 点赞服务的不可用的问题。
这些问题都交给中台解决了。各大业务模块业务子系统直接使用接口就行。
B站点赞中台的整体架构
B站架构师给出的架构图
下面是哔哩哔哩资深开发工程师 芦文超, 给出的系统架构图 整个点赞服务的中台可以分为五个部分
流量路由层决定流量应该去往哪个机房业务网关层统一鉴权、反黑灰产等统一流量筛选点赞服务thumbup-service,提供统一的RPC接口点赞异步任务thumbup-job数据层db、kv、redis
上的B站小伙伴的分层方案从架构的维度不是太好理解接下来按照尼恩的3高架构笔记中的分析套路给大家做进一步的梳理。
分层架构的二次梳理
按照尼恩的3高架构笔记中的分析套路接下来对这个案例的分层架构 接下来按照尼恩的3高架构理论一 层一 层来进行庖丁解牛。
对这个B站千亿级点赞系统服务架构设计使之成为大家的超级学习案例。
B站点赞中台的接入层架构
架构和语言无关b站使用go语言开发 尼恩的他的小伙伴们 更喜欢使用 Java。下面从Java架构的角度进行分析。
回顾一下尼恩的3高架构笔记
客户端的请求进来会先到SLB(负载均衡)然后到内部的网关通过网关再分发到具体的业务服务。
业务服务会依赖Redis、Mysql、 MQ、Nacos等中间件。 B站点赞中心做异地多活在不同地区有不同的机房他们的架构中有两个机房。
所以他们的接入层的效果如下图所示 流量路由层
用户的请求从客户端发出这个用户的请求该到哪个机房这是 流量路由层 决定的。
首先用户需要尽量路由到同一个 机房。
为什么呢虽然服务之间的数据是没有依赖的但是服务内部依赖的存储是有状态的。不同的机房之间虽然有数据同步但是毕竟会有延迟。如果用户修改了数据之后再一查查不到感觉非常困惑。
如何 路由到同一个 机房
首先使用普通dns是不行的普通的dns域名会随机解析到不同的机房中。
一个综合方案智能DNS DLB流量网关
第一个维度是智能DNS这个具体这里不做展开请参见 尼恩的3高架构笔记。
但是智能DNS也不是万能的需要接入层进行流量矫正。
所以针对同一个用户尽可能在一个机房内完成业务闭环。
流量路由层 为了解决流量调度的问题可以基于OpenResty二次开发出了DLB流量网关DLB会对接多活控制中心能够知道当前访问的用户是属于哪个机房如果用户不属于当前机房DLB会直接将请求路由到该用户所属机房内的DLB。 如果每次都随机到固定的机房再通过DLB去校正必然会存在跨机房请求耗时加长。
所以在这块也是结合客户端做了一些优化在DLB校正请求后可以将用户对应的机房IP直接通过Header响应给客户端。
这样下次请求的时候客户端就可以直接通过这个IP访问。
如果用户当前访问的机房挂了客户端需要降级成之前的域名访问方式通过DNS解析到存活的机房。
接入层的业务网关
架构和语言无关。
b站使用go语言开发 尼恩的他的小伙伴们 更喜欢使用 Java。
下面从 Java的角度进行架构分析。
业务网关包括的功能统一鉴权、反黑灰产等统一流量筛选
接入层功能之一统一鉴权
这一层从架构的维度来说可以在SpringCloud gateway 中 使用 过滤器进行 统一鉴权
具体请参见尼恩 的10Wqps推送中台架构与实操里边有详细的介绍
接入层功能2流量筛选
黑灰产,又称非法产业、非法企业或非法经济
所谓网络黑灰产指的是电信诈骗、钓鱼网站、木马病毒、黑客勒索等利用网络开展违法犯罪活动的行为。稍有不同的是“黑产”指的是直接触犯国家法律的网络犯罪“灰产”则是游走在法律边缘往往为“黑产”提供辅助的争议行为。
流量筛选这一层从架构的维度来说 可以在SpringCloud gateway 中 使用 过滤器进行 风险ip、风险用户id的 动态探测拦截。
动态探测可以使用成熟的动态探讨框架如jd的hotkey 也可以使用滑动窗口算法实现类似的动态探测组件。
具体请参见尼恩 的100Wqps三级缓存架构与实操里边有详细的介绍
B站点赞中台的服务层架构
架构和语言无关。
b站使用go语言开发 尼恩的他的小伙伴们 更喜欢使用 Java。下面从Java架构的角度进行分析B站点赞中台的服务层架构。
点赞的业务比较简单性能也可以很高。但是之后的入库的操作性能低。
所以采用消息队列进行异步消峰解耦。 实际上这里整体用的是异步批量的架构异步是一种即为重要的架构模式关于20种异步的方式请参见尼恩的深度文章20种异步你知道几种 含协程
B站点赞中台的服务层架构细分为两层
点赞服务层异步任务层
点赞服务层thumbup-service
点赞服务层接收到用户的点赞请求完成点赞的业务计算
点赞数点赞状态点赞列表等等
具体的功能参考下图 异步任务层thumbup-job
异步任务主要作为点赞数据写入、刷新缓存、为下游其他服务发送点赞、点赞数消息等功能
点赞数据写入含用户行为数据点赞、点踩、取消等的写入缓存刷新点赞状态缓存、点赞列表缓存、点赞计数缓存同步点赞消息点赞事件异步消息、点赞计数异步消息
首先是最重要的用户行为数据点赞、点踩、取消等的写入。
搭配对数据库的限流组件以及消费速度监控保证数据的写入不超过数据库的负荷的同时也不会出现数据堆积造成的C数据端查询延迟问题。 超高流量压力的异步批量处理
超高的全局流量压力
超高并发读全站点赞状态查询、点赞数查询等【读流量】超过300k
超高并发写点赞、点踩等【写流量】超过15K
采用的策略是 异步写入批量写入
异步写入
同时数据库的写入我们也做了全面的异步化处理保证了数据库能以合理的速率处理写入请求。
批量写入聚合写入
针对写流量为了保证数据写入性能B站在写入【点赞数】数据的时候在内存中做了部分聚合写入比如聚合10s内的点赞数一次性写入。
如此可大量减少数据库的IO次数。
尼恩提示异步写入批量写入是尼恩3高架构系统中一种非常核心的模式Netty源码Hotkey源码都在大量使用具体请参见尼恩3高架构笔记。
B站点赞中台的数据层架构
架构和语言无关b站使用go语言开发 尼恩的他的小伙伴们 更喜欢使用 Java。下面从Java架构的角度进行数据层架构分析。 二级缓存架构 二级缓存分布式Cache 缓存架构
缓存层Cache点赞作为一个高流量的服务缓存的设立肯定是必不可少的。
点赞系统主要使用的是CacheAside模式。
有关 CacheAside模式 具体请参见尼恩的 100Wqps 三级缓存组件架构和实操。
这一层缓存主要基于Redis缓存以点赞数和用户点赞列表为例进行介绍
实体的点赞数的缓存设计
用业务ID和该业务下的实体ID作为缓存的Key,并将点赞数与点踩数拼接起来存储以及更新 key-value count:patten:{business_id}:{message_id} - {likes},{disLikes}business_id 代表 业务id
message_id 代表 实体 id
用户的点赞列表缓存设计
一个用户在一个业务下的 所有点赞 的列表 key user:likes:patten:{mid}:{business_id} value zset , member(messageID)-score(likeTimestamp)key为 mid 与业务ID mid 代表用户 business_id 代表业务id
value则是一个ZSet,member为被点赞的实体IDscore为点赞的时间。
当改业务下某用户有新的点赞操作的时候被点赞的实体则会通过 zadd的方式把最新的点赞记录加入到该ZSet里面来
为了维持用户点赞列表的长度不至于无限扩张需要在每一次加入新的点赞记录的时候按照固定长度裁剪用户的点赞记录缓存。
该设计也就代表用户的点赞记录在缓存中是有限制长度的超过该长度的数据请求需要回源DB查询
一级本地存储架构
LocalCache - 本地缓存
本地缓存的建立目的是为了应对缓存热点问题。 本地缓存主要解决缓存击穿的问题。
在Java应用中本地缓存建议选用命中率最高的caffeine组件 其内存淘汰算法 wtiny-lfu集合了 lrf与lfu的精华非常牛掰。
具体请参考尼恩的100Wqps三级缓存组件的介绍里边对caffeine的架构和源码和算法做了穿透式的解读。
热点探测
热门事件、稿件等带来的系统热点问题包括DB热点、缓存热点
当一个稿件成为超级热门的时候大量的流量就会涌入到存储的单个分片上造成读写热点问题。
此时需要有热点探测机制来识别该热点并将数据缓存至本地并设置合理的TTL。
例如UP主 【杰威尔音乐】发布第一个稿件的时候就是一次典型热点事件。
所以本地缓存一般要结合热点探讨框架使用
有关热点探讨框架请参考尼恩的100Wqps三级缓存组件的介绍。
二级DB架构 在尼恩的架构体系中 一般是 结构化DBNOSql结合的二级架构模式
结构化DB 为业务计算提供数据支撑 如mysql、tidb 等等NOSql DB 提供历史数据支撑全量数据支撑 大数据计算支撑 如hbasemongdb 等
后面尼恩会为大家介绍左手云原生右手大数据就是基于上面的架构系统。
B站的二级DB架构也是这种经典的二级架构。
结构化数据存储
基本数据模型
点赞记录表记录用户在什么时间对什么实体进行了什么类型的操作(是赞还是踩是取消点赞还是取消点踩)等点赞计数表记录被点赞实体的累计点赞踩数量
①、第一层存储DB层 - TiDB
点赞系统中最为重要的就是点赞记录表likes和点赞计数表counts负责整体数据的持久化保存以及提供缓存失效时的回源查询能力。
表1点赞记录表 - likes :
字段
用户Mid、被点赞的实体IDmessageID、点赞来源、时间 等等
索引
联合索引Mid、messageID 用于满足业务请求。
表2点赞数表 - counts :
字段
业务IDBusinessID 、实体ID(messageID) 、实体的点赞数、点踩数等。
索引
以业务IDBusinessID实体ID(messageID)为主键
并且按照messageID维度建立满足业务查询的索引。
结构化DB的分库分表方案
由于DB采用的是分布式数据库TiDB所以对业务上无需考虑分库分表的操作
如果选用mysql可以使用shardingjdbc 进行客户端分片的计算这种方案非常普遍。
NOSql解决全量数据的数据存储压力
点赞数据的规模超过千亿级别
如何高效的利用存储介质存放这些数据才能既满足业务需求也能最大程度节省成本也是一个点赞服务正在努力改造的工程 - KV化存储
针对TIDB海量历史数据的迁移归档
迁移归档的原因(初衷)是为了减少TIDB的存储容量,节约成本的同时也多了一层存储可以作为灾备数据。
作为一个典型的大流量基础服务点赞的存储架构需要最大程度上满足两个点
①、最大的可靠性满足业务读写需求的同时具备最大的可靠性
②、最小化存储成本: 选择合适的存储介质与数据存储形态最小化存储成本
从以上两点出发考虑到KV数据在业务查询以及性能上都更契合点赞的业务形态选用 TaiShanB站自研的KV数据库 作为NoSql的存储方案。
数据一致性架构
采用的是非常经典的 cannalbinlog的架构具体如下 有关 cannalbinlog的架构和实操请参考尼恩的100Wqps三级缓存组件的介绍。
建议大家做一下实操。尤其是高可用cannal实操。
容灾架构
作为被用户强感知的站内功能需要考虑到各种情况下的系统容灾。例如当
1、存储不可用
例如当DB不可用时需要依托缓存尽可能提供服务。同理当缓存不可用时DB也需要保证自己不宕机的情况下尽可能提供服务。
2、消息队列不可用
当消息队列不可用时依托B站自研的railgun通过RPC调用的方式自动降级
3、机房灾难
切换机房 通过 流量路由层实现
4、数据同步容灾
比如点赞就遇到过因为cannalbinlog的数据同步问题断流、延迟导致的点赞计数同步延迟问题。
5、服务层的容灾和降级
1 存储db、redis等的容灾设计同城多活
作为面对C端流量的直接接口在提供服务的同时需要思考在面对各种未知或者可预知的灾难时如何尽可能提供服务
在DB的设计上点赞服务有两地机房互为灾备设计专用的proxy代理层db-proxysidecar 业务通过db-proxysidecar访问 redis和db。
db-proxysidecar为了方便业务访问使用的是 sidecar 模式有关sidecar 模式的内容具体请参见尼恩的左手云原生、右手大数据笔记。
正常情况下机房1承载所有写流量与部分读流量机房2承载部分读流量。
当DB发生故障时通过db-proxysidecar的切换可以将读写流量切换至备份机房继续提供服务。 在缓存Redis上点赞服务也拥有两套处于不同机房的集群并且通过异步任务消费TiDB的binLog维护两地缓存的一致性。
可以在需要时切换机房来保证服务的提供而不会导致大量的冷数据回源数据库。
2、数据同步容灾
点赞job对binLog的容灾设计
由于点赞的存储为TiDB,且数据量较大。
在实际生产情况中binLog会偶遇数据延迟甚至是断流的问题。
为了减少binLog数据延迟对服务数据的影响。
服务做了以下改造。
监控
首先在运维层面、代码层面都对binLog的实时性、是否断流做了监控
应对
脱离binlog由业务层thumb-service发送重要的数据信息点赞数变更、点赞状态事件等。
当发生数据延迟时程序会自动同时消费由thumbup-service发送的容灾消息继续向下游发送。
3、服务层的容灾与降级
以点赞数、点赞状态、点赞列表为例点赞作为一个用户强交互的社区功能服务对于灾难发生时用户体验的保证是放在第一位的。
所以针对重点接口B站都会有兜底的数据作为返回。
多层数据存储互为灾备
点赞的热数据在redis缓存中存有一份。kv数据库中存有全量的用户数据当缓存不可用时KV数据库会扛起用户的所有流量来提供服务。TIDB目前也存储有全量的用户数据当缓存、KV均不可用时tidb会依托于限流最大程度提供用户数据的读写服务。因为存在多重存储所以一致性也是业务需要衡量的点。首先写入到每一个存储都是有错误重试机制的且重要的环节比如点赞记录等是无限重试的。另外在拥有重试机制的场景下极少数的不同存储的数据不一致在点赞的业务场景下是可以被接受的
多地方机房互为灾备
点赞机房、缓存、数据库等都在不同机房有备份数据可以在某一机房或者某地中间件发生故障时快速切换。
点赞重点接口的降级
点赞数、点赞、列表查询、点赞状态查询等接口在所有兜底、降级能力都已失效的前提下也不会直接返回错误给用户而是会以空值或者假特效的方式与用户交互。后续等服务恢复时再将故障期间的数据写回存储。
架构的演进方向
架构方案没有最优只有更优。
B站的点赞中台后续的演进方向大致为
点赞服务单元化要陆续往服务单元化的方向迭代、演进。点赞服务平台化在目前的业务接入基础上增加迭代数据分库存储能力做到服务、数据自定义隔离。
所以以上才是“教科书式” 答案
结合 B站的方案大家回到前面的面试题
千万级数据如何做系统架构亿级数据如何做做系统架构千万级流量如何做系统架构亿级流量如何做做系统架构高并发系统如何架构
以上的方案才是完美的答案才是“教科书式” 答案。后续尼恩会给大家结合行业案例分析出更多更加劲爆的答案。当然如果遇到这类问题还可以找尼恩求助。
推荐阅读
《吃透8图1模板人人可以做架构》
《干翻 nio 王炸 io_uring 来了 图解史上最全》
《SpringCloudDubbo3 王炸 》
《响应式圣经10W字实现Spring响应式编程自由》
《4次迭代让我的 Client 优化 100倍泄漏一个 人人可用的极品方案》
《100亿级订单怎么调度来一个大厂的极品方案》
《Linux命令大全2W多字一次实现Linux自由》
《阿里一面你做过哪些代码优化来一个人人可以用的极品案例》
《网易二面CPU狂飙900%该怎么处理》
《阿里二面千万级、亿级数据如何性能优化 教科书级 答案来了》
《峰值21WQps、亿级DAU小游戏《羊了个羊》是怎么架构的》
《场景题假设10W人突访你的系统如何做到不 雪崩》
《2个大厂 100亿级 超大流量 红包 架构方案》
《Nginx面试题史上最全 持续更新》
《K8S面试题史上最全 持续更新》
《操作系统面试题史上最全、持续更新》
《Docker面试题史上最全 持续更新》
《Springcloud gateway 底层原理、核心实战 (史上最全)》
《Flux、Mono、Reactor 实战史上最全》
《sentinel 史上最全》
《Nacos (史上最全)》
《TCP协议详解 (史上最全)》
《分库分表 Sharding-JDBC 底层原理、核心实战史上最全》
《clickhouse 超底层原理 高可用实操 史上最全》
《nacos高可用图解秒懂史上最全》
《队列之王 Disruptor 原理、架构、源码 一文穿透》
《环形队列、 条带环形队列 Striped-RingBuffer 史上最全》
《一文搞定SpringBoot、SLF4j、Log4j、Logback、Netty之间混乱关系史上最全》
《单例模式史上最全》
《红黑树 图解 秒懂 史上最全》
《分布式事务 秒懂》
《缓存之王Caffeine 源码、架构、原理史上最全10W字 超级长文》
《缓存之王Caffeine 的使用史上最全》
《Java Agent 探针、字节码增强 ByteBuddy史上最全》
《Docker原理图解秒懂史上最全》
《Redis分布式锁图解 - 秒懂 - 史上最全》
《Zookeeper 分布式锁 - 图解 - 秒懂》
《Zookeeper Curator 事件监听 - 10分钟看懂》
《Netty 粘包 拆包 | 史上最全解读》
《Netty 100万级高并发服务器配置》
《Springcloud 高并发 配置 一文全懂》