Skip to content

案例 05 · FeedStream:社交 Feed 与视频内容分发系统

一句话点题:本案例练的是「内容分发的放大效应」——Feed 系统的难点不是存一条内容,而是让千万人各自刷到不同的一屏,并在大 V、爆款视频、搜索、推荐和 CDN 成本之间做取舍。


🧪 案例篇第 5 篇 · 本案例只练一件事

社交 Feed + 内容搜索 + 视频分发下的架构判断:什么时候用推模型,什么时候用拉模型,大 V 和爆款内容怎么兜住,视频为什么必须转码和 CDN,搜索 / 推荐 / 审核如何不拖垮主链路。

读完你应该能本案例靠什么练
说清 Feed 为什么不是简单查帖子列表用读写不对称和个性化首页解释时间线收件箱
判断推 / 拉 / 混合 Feed 怎么选用普通人推、大 V 拉解决扇出爆炸
看懂图片 / 视频为什么不能走业务源站用转码、分片、CDN、预热和回源解释带宽成本
把搜索、推荐、审核放进内容分发架构用召回 / 排序 / 审核召回和降级兜住体验与安全

重要提醒:下面是教学化案例,不是某个社交平台的内部图纸。 数字用于数量级推理,目的是练判断,不是给出唯一答案。


开场:为什么 Feed 不是「查我关注的人发了什么」

因为一个内容产品真正卖的不是发帖按钮,而是用户每次打开时那一屏内容。

FeedStream 是一个图文 + 短视频内容社区。用户可以关注创作者、发布图文或视频、点赞评论、搜索内容,也会看到系统推荐的内容。普通创作者只有几百粉丝,头部创作者有几百万粉丝。热门视频上线后,几十万人会在几分钟内同时点开。

第一眼看,它像是普通内容系统:

  • 用户发帖;
  • 粉丝看首页;
  • 点赞评论;
  • 搜索关键词;
  • 上传视频;
  • 推荐一些内容。

但真正上线后,最危险的不是「帖子存不下」,而是:

首页刷新太慢、大 V 一发文打爆扇出队列、爆款视频回源压垮源站、违规内容已经扩散到几百万人的时间线里。

所以这一章不写「怎么做一个帖子表」。它问一个更具体的问题:

如何把海量内容分发给不同的人,同时控制热点、排序、媒体带宽和内容安全?

这章和前几章的压力源不同:

  • StarArena 怕的是库存和支付状态。
  • PatchDesk 怕的是多租户边界。
  • DocuMind 怕的是答案可信。
  • SyncRoom 怕的是实时状态收敛。
  • FeedStream 怕的是一次写入被放大成海量读取、海量分发和海量带宽。

读前小词典

这篇会反复出现几个词,先用人话对齐一下:

人话解释
Feed信息流。用户打开首页看到的一串内容。
Timeline时间线。按某种顺序排列的一组内容 ID,可以是个人主页流,也可以是首页流。
Fan-out扇出。一条内容要分发给很多接收者。
推模型 / 写扩散发文时就把内容 ID 写进粉丝的收件箱,读的时候很快。
拉模型 / 读扩散发文时只存一份,用户刷新时再去拉取关注对象的内容。
混合模型普通人走推,大 V 走拉。避免大 V 发文时一次写爆。
大 V粉丝很多的头部创作者。它的发文会造成极端扇出。
收件箱每个用户自己的 Feed 候选列表,通常只存内容 ID,不存正文。
召回先从海量内容里粗略找一批候选。
排序 / 精排对候选内容打分,决定先给用户看哪条。
CDNContent Delivery Network,内容分发网络。把图片、视频等静态内容缓存到离用户更近的边缘节点。
回源CDN 没命中缓存,只能回到源站 / 对象存储拿内容。回源通常更慢也更贵。
转码把一个源视频加工成多种清晰度 / 码率,让不同网络都能播放。
ABRAdaptive Bitrate,自适应码率。播放器根据网络情况动态切换清晰度。
审核召回内容被判违规后,不仅要下架原文,还要从搜索、推荐、时间线、缓存里撤掉。

一、起始状态:先验证内容供给和消费,别先造推荐帝国

FeedStream 的第一版目标很朴素:让用户能关注创作者,看到关注内容,发布图文和短视频。

起始阶段的约束大概是这样:

维度起始阶段
日活用户1 万以内
创作者1,000~5,000
日发内容5,000~20,000 条
视频占比10%~20%
峰值 Feed 读取200~500 QPS
团队规模5~8 名工程师
核心目标验证有没有人发、有没有人刷、有没有互动
最不能错首页不能长期刷不出;违规内容不能无控制扩散

这时最合理的架构不是全量推荐平台,而是内容服务 + 关注关系 + 简单 Feed 读取 + 对象存储 / CDN:

用户发内容


┌────────────────────────────────────────────┐
│ 内容服务                                     │
│ 写帖子正文、媒体地址、作者、可见性、审核状态       │
└──────────────┬─────────────────────────────┘

       ┌──────────────┐
       │ 内容存储       │
       │ post / media  │
       └──────────────┘

用户刷首页


┌────────────────────────────────────────────┐
│ Feed 读取服务                                │
│ 查关注列表 → 拉取最近内容 → 简单排序 → 返回       │
└────────────────────────────────────────────┘

图片 / 视频 → 对象存储 → CDN

这不是「架构简陋」。在没有大 V、没有海量读之前,拉模型简单、灵活,足够验证产品。


二、量化假设:它不是被写入压垮,而是被读取和热点压垮

先算一笔账。假设 FeedStream 推广半年后:

日活用户:2,000,000
月活用户:10,000,000
创作者:500,000
每日新内容:1,000,000 条
视频内容:200,000 条/天
峰值发文:2,000~5,000 条/秒
峰值 Feed 刷新:50,000~150,000 QPS
普通用户粉丝:100~2,000
中腰部创作者粉丝:10,000~200,000
头部创作者粉丝:1,000,000~20,000,000
爆款视频:10 分钟内 500,000 次播放
目标:首页刷新 P95 < 500ms,发文到可见通常 < 10s
视频目标:首帧 < 2s,卡顿率尽量接近 0,CDN 命中率 > 95%
审核目标:高风险内容先审后扩散;违规内容 5 分钟内从主要分发面撤回

这个数量级里,写内容不是最大问题。真正危险的是:

  1. 读远多于写:一次发文后,可能被读几千、几万、几百万次。
  2. 粉丝分布极端倾斜:普通人几百粉,大 V 几百万粉,不能同一种扇出策略。
  3. 视频带宽是真成本:每多播放一分钟,都在烧 CDN 和带宽钱。
  4. 违规内容会被系统放大:Feed 和推荐越强,扩散越快,召回也越难。

所以 FeedStream 的架构重心不是「帖子怎么落库」,而是:

把个性化读取变快,把热点扩散变可控,把媒体分发从源站挪到边缘,把审核召回做成系统能力。


三、触发信号:什么时候说明第一版开始不够用

第一版跑起来后,不要凭感觉升级。看这些信号:

信号表现为什么这是架构问题
首页刷新越来越慢用户关注 1,000 人后,每次刷新都要聚合很多人的内容纯拉模型读放大,读路径开始扛不住
大 V 发文导致队列堆积一条内容要写入几百万粉丝收件箱纯推模型遇到头部账号扇出爆炸
热门内容正文查询打满爆款内容被反复回填正文内容正文和媒体缺少热点缓存
视频播放回源飙升新热视频上线后 CDN 未命中,源站带宽打满热点内容没有预热 / 回源合并
搜索结果搜不到新内容新内容发布几分钟后还搜不到索引新鲜度跟不上
推荐结果质量波动用户刷到大量重复、低质、过期内容召回 / 排序 / 去重链路不稳定
违规内容扩散后难撤内容删了,但 Feed、搜索、缓存里还能看到审核状态没有贯穿分发链路
点赞数忽高忽低计数缓存和真实互动日志长期不一致派生计数没有可重算来源

这些信号不是在说「数据库不够大」。它们在说:内容分发开始放大一切,包括热点、成本和错误。


四、核心矛盾:每个人都要一条自己的首页

FeedStream 的核心对象有四组:

  1. 内容 / 媒体 / 作者:发了什么,媒体在哪里,审核状态如何。
  2. 关注关系 / 可见性:谁关注谁,谁能看到这条内容,拉黑和隐私规则是什么。
  3. 时间线 / 推荐候选 / 排序结果:用户首页那一屏从哪里来,为什么这样排。
  4. 搜索 / 审核 / 互动信号:内容能不能搜到,能不能继续分发,用户如何反馈。

如果只看最简单路径,它像这样:

用户刷新首页 → 查我关注的人 → 查他们最近发的内容 → 排序返回

但真实系统必须在每一步都回答:

  • 我关注的人很多,每次都现查能不能撑住?
  • 大 V 发文时,要不要写进每个粉丝的收件箱?
  • 时间线里存正文还是只存内容 ID?
  • 推荐排序能不能在 500ms 内完成?
  • 视频播放从哪里取?CDN 没命中怎么办?
  • 内容后来被判违规,怎么从时间线、搜索、推荐、CDN 里撤掉?

所以新的架构命题变成:

Feed 是一台个性化内容分发引擎,不是一张 posts 表。

关键分层是:

内容权威层:帖子正文、媒体、审核状态、可见性
分发层:时间线收件箱、推 / 拉 / 混合扇出
排序层:候选召回、粗排、精排、去重、多样性
媒体层:转码、对象存储、CDN、预热、回源保护
安全层:审核、下架、召回、风控、可见性过滤

五、方案推演:Feed 到底推还是拉

这是本案例最重要的决策。Feed 系统的核心问题是:首页到底提前算好,还是刷新时现算?

方案 A:纯拉模型,刷新时现查

用户刷新
  └─▶ 查我关注的所有人
      └─▶ 查他们最近发的内容
          └─▶ 合并排序返回
优点代价
发文很轻,只写一份用户关注多了之后,每次刷新读放大严重
关注 / 取消关注立即生效Feed QPS 高时,读取路径很难撑住
MVP 简单难以做到 P95 < 500ms

方案 B:纯推模型,发文时写进粉丝收件箱

用户发文
  └─▶ 查粉丝列表
      └─▶ 把内容 ID 写进每个粉丝的 Feed 收件箱
优点代价
首页读取极快,直接读自己的收件箱大 V 一发文就是百万 / 千万级写入
适合读远多于写扇出队列、时间线存储压力大
可以把排序结果预先准备好一部分关注关系变化后的修正更复杂

方案 C:推拉混合,普通人推,大 V 拉

普通创作者发文 → 推进粉丝收件箱
大 V 发文       → 只写自己的作者流
用户刷新首页     → 读收件箱 + 拉取关注大 V 的新内容 + 排序合并
优点代价
普通内容读取快Feed 读取服务要合并两路候选
避免大 V 扇出爆炸大 V 内容会成为读时热点,需要缓存
能按粉丝数阈值分治阈值、灰度和中腰部账号策略要持续调

FeedStream 成长期选择:推拉混合。普通人内容写扩散,大 V 内容读时拉取,两路在 Feed 读取服务里合并。

关键不在「推还是拉谁更高级」,而在于:

粉丝分布极端倾斜,所以必须分而治之。对 99% 便宜情况优化,把 1% 会爆炸的情况单独处理。


六、关键架构决策:用 ADR 把为什么留下来

ADR 是 Architecture Decision Record,可以理解成「架构决策记录」。Feed 系统最容易在后面被人问:「为什么时间线只存 ID?为什么大 V 不推?为什么视频要异步转码?为什么审核要影响分发?」这些都应该提前写下来。

ADR-01:Feed 采用推拉混合,而不是纯推或纯拉

  • 背景:读远多于写,首页刷新必须快;但粉丝数极端倾斜,大 V 写扩散会爆炸。
  • 选择:粉丝数低于阈值的创作者走写扩散,发文时写进粉丝收件箱;头部创作者只写作者流,由粉丝刷新时拉取并合并。
  • 放弃:放弃所有账号同一种分发策略。
  • 换来:普通用户首页读取快,大 V 发文不会打爆扇出队列。
  • 风险:Feed 读取链路更复杂,需要合并、去重、排序和缓存大 V 内容。
  • 复审条件:当中腰部账号频繁触发阈值边界,需要按活跃粉丝、内容热度和账号等级动态调整策略。

ADR-02:时间线收件箱只存内容 ID,正文和媒体读时批量回填

  • 背景:一条热门内容可能进入百万用户收件箱,如果每份都存正文和媒体信息,空间会爆炸。
  • 选择:时间线收件箱存 post_id、作者、时间、轻量排序分等引用信息;读取时批量回填正文、计数和媒体地址。
  • 放弃:放弃在每个收件箱里复制完整内容。
  • 换来:空间可控,热门内容只存一份权威正文,修改审核状态时也更容易统一生效。
  • 风险:读取时多一次批量回填,热门内容正文存储会成为热点。
  • 复审条件:当回填成为瓶颈时,给热门正文、互动计数和整屏 Feed 增加短缓存。

ADR-03:视频上传后异步转码,通过对象存储 + CDN 分发

  • 背景:源视频巨大,用户网络差异大,源站直发会导致卡顿和带宽成本失控。
  • 选择:上传源视频后立即返回处理中;后台转码为多档分片和 manifest;播放时走 CDN,播放器用 ABR 按网络选择分片清晰度。
  • 放弃:放弃上传请求里同步转码,也放弃源站直接分发视频。
  • 换来:上传体验不卡,播放更流畅,带宽成本由 CDN 命中率控制。
  • 风险:上传后到可播放有延迟;转码队列和 CDN 回源都需要监控。
  • 复审条件:当爆款内容经常回源打满,需要热点预热、回源合并和多 CDN 策略。

ADR-04:审核状态必须贯穿 Feed、搜索、推荐和 CDN

  • 背景:内容平台会出现违法、有害、侵权或垃圾内容;分发系统越强,错误扩散越快。
  • 选择:内容有统一审核状态;高风险内容先审后扩散;下架事件异步通知 Feed 收件箱、搜索索引、推荐候选、缓存和 CDN;读取时也要二次检查可见性。
  • 放弃:放弃只在内容详情页隐藏违规内容的做法。
  • 换来:违规内容能从主要分发面撤回,可见性规则在写入和读取两侧都生效。
  • 风险:召回链路复杂,可能出现某个分发面漏撤。
  • 复审条件:当平台开始承载 UGC 大规模内容时,审核召回要作为一级能力,并建立下架回归测试。

七、演进后的结构与数据流

下面只画 FeedStream 的核心结构。它不是一个帖子 CRUD,而是一套内容分发、排序、媒体分发和审核召回系统。

起始路径

用户发文 → posts 表
用户刷新 → 查关注列表 → 查 posts → 返回
视频播放 → 源站文件地址

问题是:读放大、大 V 扇出、视频带宽、审核召回都没有结构化。

演进后的结构

用户发内容


┌──────────────────────────────────────────────┐
│ 内容服务                                      │
│ 写正文 / 可见性 / 审核状态 / 媒体元数据            │
└──────┬───────────────────────┬───────────────┘
       │                       │
       ▼                       ▼
┌──────────────┐       ┌──────────────────────┐
│ 内容存储       │       │ 媒体管线               │
│ post 权威副本  │       │ 上传 → 转码 → 对象存储 → CDN│
└──────┬───────┘       └──────────────────────┘


┌──────────────────────────────────────────────┐
│ Feed 分发服务                                  │
│ 普通人写扩散 → 粉丝收件箱                         │
│ 大 V 只写作者流 → 读时拉取                         │
└──────┬───────────────────────┬───────────────┘
       ▼                       ▼
┌──────────────┐       ┌──────────────────────┐
│ 时间线收件箱    │       │ 搜索 / 推荐索引          │
│ user -> post_id│       │ 候选召回 / 排序特征       │
└──────┬───────┘       └──────────┬───────────┘
       ▼                          ▼
┌──────────────────────────────────────────────┐
│ Feed 读取服务                                  │
│ 读收件箱 → 拉大 V → 回填正文 → 过滤可见性           │
│ → 排序 / 去重 / 多样性 → 返回一屏                  │
└──────────────────────────────────────────────┘

这张图的核心变化不是「多了推荐」,而是结构变清楚了:

  • 内容服务保存权威正文、媒体引用、审核状态和可见性。
  • Feed 分发服务决定推还是拉,并异步写入时间线收件箱。
  • 时间线收件箱只存内容 ID,服务于低延迟读取。
  • Feed 读取服务合并普通内容、大 V 内容、推荐候选,再做回填、过滤、排序。
  • 媒体管线把图片 / 视频从业务源站移到对象存储和 CDN。
  • 审核召回贯穿内容、Feed、搜索、推荐、缓存和 CDN。

跟一次「普通创作者发文」走到底

1. 创作者发一条图文。
2. 内容服务写入 post 权威副本,状态为待分发或已审核。
3. Feed 分发服务查粉丝列表,发现粉丝数 800。
4. 这属于普通账号,异步把 post_id 写入 800 个粉丝的时间线收件箱。
5. 粉丝刷新首页时,直接从自己的收件箱取最新 post_id。
6. Feed 读取服务批量回填正文、互动计数和媒体 URL。
7. 排序服务打分,再做去重和多样性控制。
8. 用户看到这一屏内容。

跟一次「大 V 发爆款视频」走到底

1. 大 V 上传一个短视频。
2. 上传服务把源视频存入对象存储,投递转码任务,立即返回处理中。
3. 转码服务异步生成 1080p / 720p / 480p 等分片和 manifest。
4. 内容审核通过后,内容服务标记视频可分发。
5. 因为这是大 V,Feed 分发服务不把 post_id 写入几百万粉丝收件箱,只写作者流。
6. 粉丝刷新 Feed 时,读取服务发现用户关注了该大 V,拉取作者流里的新视频。
7. 排序服务把它并入候选,如果分数足够高,进入用户首页。
8. 播放器请求 manifest 和视频分片,优先命中 CDN。
9. 如果预测会爆,系统提前预热头部分片到 CDN;未命中回源时做请求合并,避免源站惊群。

这里的关键点:

  • 大 V 内容不写扩散,避免发文时扇出爆炸。
  • 读时拉取大 V 内容必须配热点缓存,否则会把读压力转移到作者流。
  • 视频播放不走业务服务,而走对象存储 + CDN。
  • 审核没过的内容不能进入 Feed、搜索和推荐候选。

八、坏了怎么办:故障场景与兜底

故障直接后果检测方式架构兜底
纯拉模型读放大首页刷新慢,数据库被关注聚合打满Feed P95、关注数分布、查询扇出数普通用户改写扩散,预计算时间线收件箱
纯推模型遇到大 V一条内容触发百万级写入,队列堆积fanout queue lag、单 post 扇出数大 V 走读时拉取,粉丝数阈值动态调整
时间线存完整正文爆款内容被复制百万份,空间失控时间线存储膨胀收件箱只存 post_id,读时批量回填
大 V 作者流无缓存粉丝刷新时把作者流读爆作者流 QPS、热点 post 回填量热点作者流和热门正文短缓存
扇出同步阻塞发文用户发文卡住甚至失败发文延迟、扇出耗时发文只落权威副本,扇出异步队列
CDN 未命中率飙升视频首帧慢,源站带宽打满CDN hit ratio、origin egress热点预热、分层缓存、回源请求合并
转码队列堆积视频上传后长时间不可播转码队列长度、任务耗时转码 worker 弹性扩容,冷内容少转码档
搜索索引滞后新内容搜不到或旧违规内容还能搜到索引新鲜度、旧状态命中近实时增量索引,下架事件优先处理
推荐候选重复 / 低质用户刷到重复内容或垃圾内容重复率、负反馈率、停留时长去重、多样性规则、质量过滤、反馈闭环
违规内容已扩散Feed、搜索、缓存里仍可见下架回归、内容状态扫描审核状态贯穿全链路,下架事件召回各索引和缓存
可见性只在前端判断私密内容进入不该看的人的 Feed权限穿透测试、投诉扇出和读取两侧都强制可见性过滤
互动计数长期错误点赞数、评论数和真实日志不一致计数对账、异常波动计数可缓存,但以互动日志可重算

内容分发的成熟度,不是看首页能不能刷出内容,而是看热点、违规、回源、推荐退化这些放大效应有没有被结构兜住。


📌 拿模板验证这次推演

本案例不是重写社交 Feed 或视频流模板,而是把「内容社区」里最容易互相影响的几条链路放在一起推演。

可复用模板 / 章节本案例复用什么本案例重点补什么
社交信息流推 / 拉 / 混合、时间线收件箱、大 V 扇出用具体内容社区解释为什么普通人推、大 V 拉
视频流媒体转码、多码率、对象存储、CDN、预热把视频分发放进 Feed 热点内容场景
搜索引擎倒排索引、召回 + 精排、索引新鲜度说明站内搜索和推荐候选都需要索引与过滤
通知 / 推送系统异步通知、去重、限频互动提醒不能阻塞发文和 Feed 读取
规模化的力学热点、扇出、缓存、读写放大把大 V、爆款视频、CDN 回源都看成放大问题
安全与多租户架构可见性、权限、隔离把私密内容、拉黑、审核状态落到分发链路

读法建议:先读本章,再回看 社交信息流模板视频流媒体模板。你会更容易看懂:Feed 和视频看似两个系统,但热点和分发成本会把它们绑在一起。


🎯 随堂检验

🤔FeedStream 为什么不应该对所有创作者都使用纯推模型?
  • A因为推模型读性能一定差
  • B因为头部创作者粉丝太多,一条内容会触发百万级写扩散,需要大 V 走读时拉取
  • C因为时间线不能预计算
🤔时间线收件箱里为什么通常只存 post_id,不存完整正文?
  • A因为正文不能存数据库
  • B因为热门内容会被很多收件箱引用,复制完整正文会让空间和更新成本爆炸
  • C因为 Feed 不需要正文
🤔爆款视频上线后源站被打满,最直接说明什么没做好?
  • A帖子表字段太少
  • BCDN 命中、热点预热或回源保护没做好
  • C用户关注关系太复杂
🤔违规内容已经进入 Feed、搜索和推荐后,只删除帖子详情页够不够?
  • A够,因为详情页没了就没人能看
  • B不够,还要从时间线、搜索索引、推荐候选、缓存和 CDN 里召回
  • C不用管,等缓存过期

本案例小结

  • Feed 不是查 posts 表,而是个性化分发引擎。 每个人的首页都不同,读远多于写,所以读取路径是主战场。
  • 推拉混合是大规模 Feed 的核心取舍。 普通人走写扩散换读取速度;大 V 走读时拉取避免扇出爆炸。
  • 时间线存引用,正文读时回填。 这是空间、热点缓存和审核一致性的关键。
  • 视频内容必须离开业务源站。 转码、多码率、对象存储、CDN、预热和回源保护决定播放体验和带宽成本。
  • 推荐和搜索是召回 + 排序漏斗。 不要试图每次刷新实时重算全网,而是先召回候选,再对小集合打分。
  • 审核召回是分发系统的一部分。 内容被系统扩散到哪里,下架就必须能撤到哪里。

承上启下:这一章把内容 Feed、搜索、推荐和视频 CDN 放进同一个内容社区。下一章如果继续写 AI Agent / 编码 Agent,压力会再次变化:重点会从内容分发,转向工具调用、权限、沙箱、记忆、上下文和人工审批。


相关链接

💬 评论