写点什么

架构训练营模块二作业

用户头像
Geek_e0c25c
关注
发布于: 2021 年 04 月 18 日

【作业要求】

  1. 对照模块 2 讲述的复杂度分析方法,分析微信朋友圈的复杂度;

  2. 针对各个复杂度,画出你的架构设计方案(无需做备选方案,只需要最终的方案即可);

  3. 给出你的架构方案中关键的设计理由。

  4. 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 万/秒。


【复杂度分析】

朋友圈从业务功能上分为发朋友圈、刷朋友圈、点赞评论三大功能,但是海量用户,读写性能要求很高,因此属于低业务复杂度、高质量复杂度的场景。


难点一:

对于用户如何刷到自己朋友圈信息流数据的方案设计,通常有两种方案:

  1. 为每个用户维护一个信息流列表,有人发朋友圈记录时就把该记录添加到他所有朋友的信息流列表中,其他用户刷朋友圈时只需要读取自己的信息流列表。

  2. 朋友圈记录都存在数据库里,用户在刷朋友圈的时候读取自己所有朋友所发的朋友圈记录。

分析:

方案一发朋友圈的逻辑复杂而刷的逻辑简单,方案二发简单但是刷复杂且性能压力大。

考虑到朋友圈业务场景读 QPS 远大于写 TPS,并且方案一中的复杂逻辑可以异步实现以致用户无感知,因此选择方案一


难点二:

发朋友圈支持图片/视频,占用空间较大。

  • 图片不宜直接存 MySQL 中。

  • 由于每条朋友圈记录都会复制到其他朋友的信息流列表中,因此如果每一个列表中都复制一份图片/视频数据,将造成极大的存储空间浪费和数据拷贝传输压力。

因此,图片/视频单独存放在对象存储服务器,朋友圈记录表和用户的信息流记录表中仅存放图片/视频的 URL 地址,客户端可以直接访问而不需要再通过应用服务器传输。


【架构分析】

首先单独分析发朋友圈、刷朋友圈和点赞评论的架构方案


发朋友圈:

  1. 应用服务器通过负载均衡实现任务分配。

  2. 每条记录存入 MySQL 集群,图片/视频存放对象存储服务器,URL 地址和记录数据存在一起,MySQL 集群按用户 ID 进行分片存储。

  3. 将该记录添加到当前用户所有朋友的信息流列表,使用消息队列异步写入。

  4. 用户的信息流数据按用户 ID 分片存储,这样可以优化刷朋友圈时的读取性能。

  5. 由于用户刷朋友圈时优先看最近发的,可以采用缓存模型来提供性能:热数据方案在 Redis 中,超过一定时间后降为冷数据迁移到 MySQL。


刷朋友圈:

  1. 应用服务器通过负载均衡实现任务分配。

  2. 读取该用户的信息流列表:

  3. 先读取 Redis 集群中近期的信息流

  4. 按需读取 MySQL 集群中的信息流冷数据

  5. 根据信息流列表中的记录信息到评论数据库中读取点赞/评论信息。

  6. 图片/视频只返回 URL 地址,由客户端直接读取 URL 展示。


点赞/评论:

  1. 应用服务器通过负载均衡实现任务分配。

  2. 每条点赞/评论记录存入 MySQL 集群,数据提供分片存储即可。

  3. 可以和朋友圈发记录数据共用一个 MySQL 集群。


【总体架构及原因】

综合考虑发朋友圈、刷朋友圈和点赞评论三大核心场景的架构设计,可以将应用服务器合并使用,因此总体架构设计图如下:


发布于: 2021 年 04 月 18 日阅读数: 42
用户头像

Geek_e0c25c

关注

还未添加个人签名 2020.09.13 加入

还未添加个人简介

评论

发布
暂无评论
架构训练营模块二作业