中文 EN

系统设计 Lab

社交 news feed 的成败系于 fan-out 的取舍:写入时把帖子推进每个 follower,还是读取时拉取再合并。

调节日活用户、发帖速率、平均 follower 数和 celebrity follower 数、feed 读取量、feed 大小和 ranking 成本。设计会从读取时 pull 合并,演进到带 feed cache 的 push fan-out、对 celebrity 特殊处理的混合方案、ranking pipeline,最后是跨 region 的 sharded store。

分步讲解

一步一步把它想清楚

常规演进场景

从左到右点击,就是预设的演示路径。每张卡片都会改变 workload 输入。

Workload

这些是输入,不是预设好的架构阶段。

推荐形态

当前架构路径
社交 news feed 架构图 白板风格的社交 news feed 架构图:client、edge 和 API gateway、带 feed cache 的 fan-out service、post store 和 follow graph,以及 ranking 加异步 worker。 Client Edge / API Fan-out + cache Store Ranking / 异步 Client post + read API gateway post + feed Feed service 组装 feed Fan-out worker 写入时 push Feed cache 每个用户的 feed Post store 帖子 + 媒体 Follow graph 谁关注了谁 Ranking service 给 feed 打分 Celebrity merge 读取时 pull
Client
Client 创建帖子,并加载首页 feed 时间线
Edge / API
API gateway 把帖子写入和 feed 读取路由到对应的 service
Feed service 提供首页 feed,读 cache 并合并额外内容
Fan-out + cache
Fan-out worker 把每条新帖子推进每个 follower 的 feed cache
Feed cache 保存预计算好的 feed,让读取只需一次 cache fetch
Store
Post store 持久保存每条帖子,随量增长做 shard
Follow graph follower 和 followee 的边,用来算 fan-out 的目标
Ranking / 异步
Ranking service 按预测的相关性给 feed item 打分并重排
Celebrity merge 在读取时合并超大账号的帖子,而不是做 fan-out

瓶颈

写 fan-out 放大

Celebrity fan-out 成本

Feed cache 内存

读取合并成本

帖子写 throughput

为什么会变

    决策权衡

    Fan-out 策略

    Feed cache

    Celebrity 特殊处理

    Post-store sharding

    Ranking pipeline

    有出处支撑的规则

    这些是模型背后那些经得起时间考验的 system design 论断。而 slider 的具体阈值,则被刻意标注为教学用的假设。

    已验证的规则

    Feed 通常用 fan-out-on-write,对 celebrity 用混合方案

    经典写法在写入时把帖子 push 给 follower 来预计算 feed,再对超高 follower 数的账号特殊处理:在读取时合并它们的帖子。

    System Design Primer
    已验证的规则

    Redis 用 sorted list 支撑每个用户的 feed cache

    in-memory 的有序结构保存每个用户的 feed,于是一次 feed 读取就是一次快速的 range fetch,而不是一次 database join。

    Redis Docs
    已验证的规则

    Kafka 把帖子写入和繁重的 fan-out 工作解耦

    一个持久 log 让帖子写入能立刻返回,而 fan-out worker 异步消费 event,把内容 push 进 follower 的 feed。

    Apache Kafka
    已验证的规则

    DynamoDB 风格的 partition 扩展 post store 和 graph store

    当数据集撑爆单机时,按 key 给帖子和 follow 边做 partition,把 storage 和写 throughput 分散到多个 node 上。

    AWS DynamoDB

    教学用假设

    • 写 fan-out 建模为 posts/s 乘以平均 follower 数;读 fan-out 建模为 feed reads/s 乘以合并的 followee 数。
    • 单 node 的 fan-out、cache 和 store 预算是保守的教学数字,不是厂商上限。
    • Celebrity 混合方案把最大的账号从写 fan-out 中移除,改成每次读取时加一点小合并。