Skip to content

第 11 章:设计信息流系统

简介

信息流系统持续展示来自用户社交关系的帖子,包括状态、照片、视频和链接。例如 Facebook 动态、Instagram 信息流和 Twitter 时间线。本章讨论可扩展信息流系统的设计。


第一步:理解问题

需求

  1. **平台:**支持网页端和移动端。
  2. 功能:
    • 用户可以发布帖子。
    • 用户可以在信息流中查看好友的帖子。
  3. 排序:为简化设计,按时间倒序排列。
  4. 规模:
    • 每位用户最多有 5000 个好友。
    • 日活跃用户(DAU)为 1000 万。
    • 信息流可包含文字、图片和视频。

第二步:概要设计

总览

设计包含两条主要流程:

  1. **发布信息流:**用户发布帖子后,系统将其写入数据库,并分发到好友的信息流。
  2. **构建信息流:**用户请求信息流时,系统按时间倒序聚合好友帖子。

信息流 API

  1. 发布 API:

    • 接口:POST /v1/me/feed
    • 参数:content(帖子正文)和 auth_token(身份验证)。
  2. 获取 API:

    • 接口:GET /v1/me/feed
    • 参数:auth_token(身份验证)。

发布信息流

  <img src="/images/chapter-11/feed-publishing.png" alt="发布信息流" width="400" />
  1. **用户交互:**用户通过发布 API 提交帖子。
  2. **负载均衡器:**将流量分配到 Web 服务器。
  3. **Web 服务器:**验证请求并转发给相应服务。
  4. **帖子服务:**将帖子存入数据库和缓存。
  5. **扇出服务:**把帖子分发到好友的信息流缓存。
  6. **通知服务:**通知好友。

构建信息流

  <img src="/images/chapter-11/news-feed-building.png" alt="构建信息流" width="400" />
  1. **用户交互:**用户调用获取 API 请求信息流。
  2. **负载均衡器:**将流量分配到 Web 服务器。
  3. **Web 服务器:**将请求转发给信息流服务。
  4. **信息流服务:**从信息流缓存获取帖子 ID,再从数据库或缓存读取完整帖子。

第三步:详细设计

发布流程详解

  1. Web 服务器:

    • 使用 auth_token 验证用户身份。
    • 执行限流,防止垃圾内容。
  2. 扇出服务:

    • **写时扇出:**发布时将帖子推送到好友的信息流。

      • **优点:**更新及时,读取信息流速度快。
      • **缺点:**好友众多的用户会消耗大量资源。
    • **读时扇出:**读取时拉取帖子。

      • **优点:**对不活跃用户更节省资源。
      • **缺点:**读取信息流更慢。
    • **混合方案:**多数用户使用推送;连接数极高的用户(如名人)使用拉取。

      发布流程详解

    扇出服务的工作流程:

    1. **获取好友 ID:**从图数据库读取好友列表。

    2. **根据缓存过滤好友:**读取用户设置,排除被静音的好友或不符合分享范围的好友。

    3. **发送到消息队列:**将过滤后的好友列表及新帖 ID 送入队列。

    4. **扇出工作进程:**从消息队列取数据并更新信息流缓存。为节约内存,缓存保存 <post_id, user_id> 映射,而非完整的用户和帖子对象。

    5. **写入信息流缓存:**将新帖 ID 加入好友的信息流缓存。设置可配置的数量上限,仅保存近期帖子,控制缓存内存占用。

      扇出服务

获取信息流详解

缓存架构

缓存分为五层:

  1. **信息流缓存:**保存帖子 ID,便于快速读取。

  2. **内容缓存:**保存帖子详情;热门帖子放在热缓存中。

  3. **社交图谱缓存:**保存用户关系数据。

  4. **行为缓存:**记录点赞、回复和分享等操作。

  5. **计数缓存:**保存点赞数、回复数、关注者数等。

    缓存架构

关键优化

扩展

  1. 数据库扩展:
    • 水平扩容与分片。
    • 使用只读副本处理高流量查询。
  2. **无状态 Web 层:**保持 Web 服务器无状态,以便水平扩容。

缓存

  1. 将频繁访问的数据保存在内存中。
  2. 使用多层缓存降低延迟和数据库负载。

可靠性

  1. **一致性哈希:**将请求均匀分配到服务器。
  2. **消息队列:**解耦系统组件并缓冲流量。

监控

  1. 跟踪 QPS(每秒查询数)和延迟等关键指标。
  2. 监控缓存命中率,并相应调整配置。