第 11 章:设计信息流系统
简介
信息流系统持续展示来自用户社交关系的帖子,包括状态、照片、视频和链接。例如 Facebook 动态、Instagram 信息流和 Twitter 时间线。本章讨论可扩展信息流系统的设计。
第一步:理解问题
需求
- **平台:**支持网页端和移动端。
- 功能:
- 用户可以发布帖子。
- 用户可以在信息流中查看好友的帖子。
- 排序:为简化设计,按时间倒序排列。
- 规模:
- 每位用户最多有 5000 个好友。
- 日活跃用户(DAU)为 1000 万。
- 信息流可包含文字、图片和视频。
第二步:概要设计
总览
设计包含两条主要流程:
- **发布信息流:**用户发布帖子后,系统将其写入数据库,并分发到好友的信息流。
- **构建信息流:**用户请求信息流时,系统按时间倒序聚合好友帖子。
信息流 API
发布 API:
- 接口:
POST /v1/me/feed - 参数:
content(帖子正文)和auth_token(身份验证)。
- 接口:
获取 API:
- 接口:
GET /v1/me/feed - 参数:
auth_token(身份验证)。
- 接口:
发布信息流
<img src="/images/chapter-11/feed-publishing.png" alt="发布信息流" width="400" />
- **用户交互:**用户通过发布 API 提交帖子。
- **负载均衡器:**将流量分配到 Web 服务器。
- **Web 服务器:**验证请求并转发给相应服务。
- **帖子服务:**将帖子存入数据库和缓存。
- **扇出服务:**把帖子分发到好友的信息流缓存。
- **通知服务:**通知好友。
构建信息流
<img src="/images/chapter-11/news-feed-building.png" alt="构建信息流" width="400" />
- **用户交互:**用户调用获取 API 请求信息流。
- **负载均衡器:**将流量分配到 Web 服务器。
- **Web 服务器:**将请求转发给信息流服务。
- **信息流服务:**从信息流缓存获取帖子 ID,再从数据库或缓存读取完整帖子。
第三步:详细设计
发布流程详解
Web 服务器:
- 使用
auth_token验证用户身份。 - 执行限流,防止垃圾内容。
- 使用
扇出服务:
**写时扇出:**发布时将帖子推送到好友的信息流。
- **优点:**更新及时,读取信息流速度快。
- **缺点:**好友众多的用户会消耗大量资源。
**读时扇出:**读取时拉取帖子。
- **优点:**对不活跃用户更节省资源。
- **缺点:**读取信息流更慢。
**混合方案:**多数用户使用推送;连接数极高的用户(如名人)使用拉取。

扇出服务的工作流程:
**获取好友 ID:**从图数据库读取好友列表。
**根据缓存过滤好友:**读取用户设置,排除被静音的好友或不符合分享范围的好友。
**发送到消息队列:**将过滤后的好友列表及新帖 ID 送入队列。
**扇出工作进程:**从消息队列取数据并更新信息流缓存。为节约内存,缓存保存
<post_id, user_id>映射,而非完整的用户和帖子对象。**写入信息流缓存:**将新帖 ID 加入好友的信息流缓存。设置可配置的数量上限,仅保存近期帖子,控制缓存内存占用。

获取信息流详解
缓存架构
缓存分为五层:
**信息流缓存:**保存帖子 ID,便于快速读取。
**内容缓存:**保存帖子详情;热门帖子放在热缓存中。
**社交图谱缓存:**保存用户关系数据。
**行为缓存:**记录点赞、回复和分享等操作。
**计数缓存:**保存点赞数、回复数、关注者数等。

关键优化
扩展
- 数据库扩展:
- 水平扩容与分片。
- 使用只读副本处理高流量查询。
- **无状态 Web 层:**保持 Web 服务器无状态,以便水平扩容。
缓存
- 将频繁访问的数据保存在内存中。
- 使用多层缓存降低延迟和数据库负载。
可靠性
- **一致性哈希:**将请求均匀分配到服务器。
- **消息队列:**解耦系统组件并缓冲流量。
监控
- 跟踪 QPS(每秒查询数)和延迟等关键指标。
- 监控缓存命中率,并相应调整配置。