当前位置:首页 > 每日看点

微博和知乎中的 feed 流是如何实现的?

卡卷网1年前 (2025-05-03)每日看点281

Twitter 架构演进

Twitter 的两个主要业务是:

  1. 发推文: 用户可以向其粉丝发布新消息(平均 4.6k 请求 / 秒,峰值超过 12k 请求 / 秒)。(2012年[2])
  2. 看推文: 用户可以查阅他们关注的人发布的推文(300k 请求 / 秒)。

1. 读扩散

读扩散处理每秒 12K 次发推文还是很简单的, Twitter 的挑战主要是 300K 查看推文请求.

看推文时,首先查找关注的所有人,查询这些被关注用户发布的推文, 并按时间顺序合并

SQL 伪代码:

SELECT * FROM posts WHERE user_id IN (SELECT user_id FROM follows WHERE follower_id = :user_id) ORDER BY created_at DESC

微博和知乎中的 feed 流是如何实现的?  第1张

[1]

2. 写扩散

  • 发推文时: 查找所有粉丝, 写入所有粉丝的 timeline 中
  • 看推文时: 读取 timeline

微博和知乎中的 feed 流是如何实现的?  第2张

3. 演进

  • 推特第一版使用读扩散, 系统很难承受 300K看推文的负载
  • 推特第二版使用写扩散, 一条推文平均推送 75 个粉丝, 所以 timeline 的写压力大约 345K, 读压力是 300K

写扩散看起来很美好, 但是隐患是一些用户有超过 3000 万的粉丝, 如果该用户发推文, 那么写入 3000 万用户的 timeline (而 Twitter 尝试在 5 秒内向粉丝发送推文)

最终: Twitter 已经稳健地实现了写扩散,逐步转向了读写混合模式

Twitter 在技术分享[2]中没有透露实现细节, 下面是我的架构设计

读写混合模式 架构设计

1. 名词解释

  • 粉丝收件箱/timeline: 关注页的信息流(微博、朋友圈).
  • 发件箱: 作者发布的内容
  • 写扩散: 作者发布消息后, 立即推送给粉丝的 "粉丝收件箱"
  • 读扩散: 作者发布消息后, 不推送给粉丝. 粉丝获取信息流时, 遍历关注列表中的作者, 拉取 "发件箱" 中的新内容.
  • 大V: 粉丝数超过 10 万的用户定义为大V, 大V 不可降级为小V.

2. 作者发布内容时

  • 小V : 采用写扩散模式, 写入 所有粉丝 的 "粉丝收件箱"
  • 大V : 仅写入 活跃粉丝 的 "粉丝收件箱", 离线粉丝通过读扩散获取

流程图:

微博和知乎中的 feed 流是如何实现的?  第3张

2.1. 什么是 "活跃粉丝"?

  • 粉丝登录时, 查询自己关注的所有大 V, 注册到当天的 "活跃粉丝" 中
  • 大 V 发内容时, 查今天的 "活跃粉丝" 和昨天的 "活跃粉丝",合并 2 个结果作为大 V 活跃粉丝 (1-2天 内登录的都是活跃粉丝)

<---- 昨日 ---->|<---- 今日 ----> [ 活跃粉丝 ][ 活跃粉丝 ] <-------------------------> 合并后的大V活跃粉丝 (1-2天内登录)

好处:

  • 大 V 查询对 关系表 的压力降低到 0 QPS
  • 减少大 V 写扩散对 "粉丝收件箱" 的压力

1-2 天登录的用户有点多, 如何减少活跃粉丝量?

缩短时间, 比如 10-20 分钟存在心跳的用户

3. 粉丝登录时

  • 查询用户关注的大V列表
  • 查询"发件箱"
  • 写入新内容到"粉丝收件箱"
  • 计算红点

流程图:

微博和知乎中的 feed 流是如何实现的?  第4张

4. 粉丝读取内容时

  • 查询 "粉丝收件箱"

"粉丝收件箱" 数据结构 (Redis ZSet):

# Score: 内容更新时间戳 # Value: 内容ID content_id_1 -> 1704240000 (对应 2024-01-03 00:00:00) content_id_2 -> 1704153600 (对应 2024-01-02 00:00:00) ...

5. 粉丝关注作者时

主线逻辑:

  • 查询作者最近发布内容(大V有缓存), 写入 "粉丝收件箱" (100ms)

分支逻辑:

  • 判断作者是否大V: (1ms)
  • 如果是:
    • 修改粉丝 followBigV 表 (1ms)

  • 如果不是, 且粉丝数不超 10 万:
    • 结束
  • 如果不是, 且粉丝数超 10 万:
    • 该作者标记为大V (1ms)
    • 异步:
      • 查询作者所有粉丝 (10s)
      • 为每个粉丝 followBigV (关注的大V) 添加此新晋大V (100S)

微博和知乎中的 feed 流是如何实现的?  第5张

6. 粉丝取消关注时

主线逻辑:

  • 从粉丝收件箱删除作者内容 (大V 有缓存) (100ms)
  • 如果是大 V, 从粉丝关注的大V列表删除作者

微博和知乎中的 feed 流是如何实现的?  第6张

详细设计

1. 大V列表如何存储?

  • 每个用户关注的大V列表, 因为数量有限, 存储在单个 key 中
  • 预估: 用户关注 100 个大V, 该 key 约为 1KB

followBigV 数据结构:

{ // 用户关注的大 V ID 列表 "bigVIds": ["10001", "10002", "10003", "10004", "10005"], // 上次登录刷新时间 "lastRefreshTime": "2024-01-01 00:00:00" }

2. 如何降低"粉丝收件箱"的存储成本?

  • 采用冷热数据分离.

冷备:

  • 将 1 个月 未活跃用户的 "粉丝收件箱" 数据从 Redis 迁移到 DB, 标记冷备.
  • 存在冷备标记 cold:<UserID> -> '1' 表示用户数据被冷备

用户再次登录加载冷备:

  • 检查冷备标记.
  • 若标记存在 则从 DB 读取数据重新加载到 Redis

用户登录流程图:

微博和知乎中的 feed 流是如何实现的?  第7张

3. "粉丝收件箱"的写性能优化

  • 采用批量写入 (Pipeline) 能带来 1-2 个数量级的提升 (Redis 单机可达 200-300 万 QPS)

参考

[1] DDIA: ddia.vonng.com/#

[2] Twitter Timelines at Scale infoq.com/presentations

扫描二维码推送至手机访问。

版权声明:本文由卡卷网发布,如需转载请注明出处。

本文链接:https://www.kajuan.net/ttnews/2025/05/12838.html

分享给朋友:

相关文章

知乎创作收益高吗?

知乎创作收益高吗?

高啊,主要是大多数人不知道怎么做。(这是以前写的,请看到最后) 我之前就是傻傻写问答,文章,结果一毛钱收益没有。 知乎上收益高的主要有盐选,好物推荐,致知计划,付费咨询。1、盐选吧,是写故事,小说类的天堂,还有就是大咖们的地盘了,难度高。…

手机买16+256的还是12+512的好?

手机买16+256的还是12+512的好?

到底选大内存还是大存储,一直以来是很多朋友的纠结点,大内存意味着可以应用多开不卡顿,大存储则是可以存入更多文件、应用,如果两个配置价格差距不大(如0-200元),确实有点难选。 不过从实际体验出发,大存储的手机显然更应该优先选择才是。首先,…

马云也搞不明白:为什么现在用户偏爱微信支付,而不是支付宝?

这题我会,我教马云一招。 你直接把你那破比支付宝的代码全删了,重新写一个。 打开支付宝直接就是一个大大的支付码,然后右上角按一下就是扫一扫。你要是还想保留你的其他那些乱七八糟的功能,麻烦将他们全部做到下拉菜单里。你这么设计我不说你能干死微信…

Redmi 为什么可以把性价比做得那么高?

一位修手机的老大哥曾经跟我说过,红米1那个手机,除了处理器还凑活,其余零部件,就是市面上山寨机那种。 其实红米性价比并不算极致,而且一直都有竞争者,从原来的群魔乱舞,到后来的荣耀,魅蓝,一加,再到现在的IQOO和realme。 红米的方法也…

提升自己最快的方式是什么?

提升自己最快的方式是什么?

1. 稻盛和夫说过: “改变自己最快的方法就是做自己害怕的事,不敢做的事,认为自己做不到,觉得不可能的事。如果在自己的舒适区待久了,就会丧失斗志,如果想快速的改变,可以坚持去做一些对自己有益的事。 2. 早睡早起,坚持运动 保持旺盛的精力,…

为什么有人觉得华为mate60只值2000?

为什么有人觉得华为mate60只值2000?

你以为买Mate60的人真的傻?真的那么爱国? 国庆前,我家那傻子加价800多买了一台Mate60,当时还被我骂他是傻子。 可是他说一回到公司就被老板同事朋友看到,拿去反复查看,都在惊叹他这么快就买到新机。 跟亲戚朋友聚会,别人一看就知道他…

发表评论

访客

看不清,换一张

◎欢迎参与讨论,请在这里发表您的看法和观点。