架构训练营模块二作业
【作业要求】
对照模块 2 讲述的复杂度分析方法,分析微信朋友圈的复杂度;
针对各个复杂度,画出你的架构设计方案(无需做备选方案,只需要最终的方案即可);
给出你的架构方案中关键的设计理由。
3~5 页 PPT 即可,涵盖复杂度分析、架构设计、设计理由。
【需求分析】
在网上查到一些朋友圈的业务数据:
“每天有 7.8 亿人进入朋友圈,1.2 亿人发朋友圈,每天朋友圈的浏览总量为 100 亿次,晚上 8 到 9 点刷朋友圈人的最多。”
由于未查到峰值数据,所以暂时以每天数据量估算性能指标(假设高峰期为晚上 8 点到 9 点这一小时):
假设刷朋友圈 25%的量发生在高峰期,即一小时刷 25 亿次,平均 QPS 约 70 万/秒,峰值 QPS 按三倍计约 200 万/秒。
同样假设发朋友圈 25%的量在高峰期,即一小时发 3 千万条,平均 TPS 约 1 万/秒,峰值 TPS 按三倍计约 3 万/秒。
同样假设 25%的点赞评论行为发生在高峰期,并假设每条记录平均有 10 条点赞和评论,即一小时点赞评论 3 亿条,平均 TPS 约 10 万/秒,峰值 TPS 按三倍计约 30 万/秒。
对于图片/视频,需要放到对象存储服务器,读写峰值指标分别对应发、刷朋友圈,即写 TPS 3 万/秒,读 QPS 200 万/秒。
【复杂度分析】
朋友圈从业务功能上分为发朋友圈、刷朋友圈、点赞评论三大功能,但是海量用户,读写性能要求很高,因此属于低业务复杂度、高质量复杂度的场景。
难点一:
对于用户如何刷到自己朋友圈信息流数据的方案设计,通常有两种方案:
为每个用户维护一个信息流列表,有人发朋友圈记录时就把该记录添加到他所有朋友的信息流列表中,其他用户刷朋友圈时只需要读取自己的信息流列表。
朋友圈记录都存在数据库里,用户在刷朋友圈的时候读取自己所有朋友所发的朋友圈记录。
分析:
方案一发朋友圈的逻辑复杂而刷的逻辑简单,方案二发简单但是刷复杂且性能压力大。
考虑到朋友圈业务场景读 QPS 远大于写 TPS,并且方案一中的复杂逻辑可以异步实现以致用户无感知,因此选择方案一。
难点二:
发朋友圈支持图片/视频,占用空间较大。
图片不宜直接存 MySQL 中。
由于每条朋友圈记录都会复制到其他朋友的信息流列表中,因此如果每一个列表中都复制一份图片/视频数据,将造成极大的存储空间浪费和数据拷贝传输压力。
因此,图片/视频单独存放在对象存储服务器,朋友圈记录表和用户的信息流记录表中仅存放图片/视频的 URL 地址,客户端可以直接访问而不需要再通过应用服务器传输。
【架构分析】
首先单独分析发朋友圈、刷朋友圈和点赞评论的架构方案。
发朋友圈:
应用服务器通过负载均衡实现任务分配。
每条记录存入 MySQL 集群,图片/视频存放对象存储服务器,URL 地址和记录数据存在一起,MySQL 集群按用户 ID 进行分片存储。
将该记录添加到当前用户所有朋友的信息流列表,使用消息队列异步写入。
用户的信息流数据按用户 ID 分片存储,这样可以优化刷朋友圈时的读取性能。
由于用户刷朋友圈时优先看最近发的,可以采用缓存模型来提供性能:热数据方案在 Redis 中,超过一定时间后降为冷数据迁移到 MySQL。
刷朋友圈:
应用服务器通过负载均衡实现任务分配。
读取该用户的信息流列表:
先读取 Redis 集群中近期的信息流
按需读取 MySQL 集群中的信息流冷数据
根据信息流列表中的记录信息到评论数据库中读取点赞/评论信息。
图片/视频只返回 URL 地址,由客户端直接读取 URL 展示。
点赞/评论:
应用服务器通过负载均衡实现任务分配。
每条点赞/评论记录存入 MySQL 集群,数据提供分片存储即可。
可以和朋友圈发记录数据共用一个 MySQL 集群。
【总体架构及原因】
综合考虑发朋友圈、刷朋友圈和点赞评论三大核心场景的架构设计,可以将应用服务器合并使用,因此总体架构设计图如下:
版权声明: 本文为 InfoQ 作者【Geek_e0c25c】的原创文章。
原文链接:【http://xie.infoq.cn/article/a5181c9e0327ed6e2d0f9dddd】。文章转载请联系作者。
评论