当前位置:首页 > 每日看点 > 正文内容

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

卡卷网9个月前 (05-03)每日看点192

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

分享给朋友:

相关文章

有什么音乐软件可以全部免费下载歌曲?

有什么音乐软件可以全部免费下载歌曲?

作为音乐发烧友,我几乎把市面上所有的发烧碟、试音碟,全都给收藏,下载下来了!音质都是无损的,品质特别高,有5.1环绕的、有DTS的、有中文的、有英文的。大家可以看看这个音乐目录,大概有30万张专辑。有需要下载软件的朋友,可以双击屏幕,然后搓...

怎么免费看电视地方台和央视台?

怎么免费看电视地方台和央视台?

免费看央视和地方台,办法当然有,而且太多了,我怕你挑花了眼用不过来……首先题主需要明确一点,你家的电视需要是基于安卓系统的智能电视,能安装第三方安卓电视软件。比如小米电视、雷鸟电视等等;如果不是,你至少需要购置一个电视盒子,比如小米电视盒子...

有没有推荐什么手游搬砖,或者是用手机就能做的工作能日入100左右就好了?

有没有推荐什么手游搬砖,或者是用手机就能做的工作能日入100左右就好了?

大家好,我是思聪。思聪游戏搬砖社每天分享真实靠谱的游戏赚钱的方法。整个游戏的攻略用一句话概括就是:打元宝兑换平台物品,xx元宝兑换一个分红物品。你把你打游戏得来的元宝去兑换平台的分红物品,就能每天领取xx元的分红。(具体看是哪个分红物品,比...

为什么大家不再提 5G 了?

现在看来,只有美国那种5g的思路是对的。美国的运营商一开始就发现5g和4g并没有质的飞跃,无非就是提升频率/降低穿透力/提升带宽的故事。而美国运营商又是自负盈亏,因此一开始就仅在人口高密度地区或富裕地区布置5g。虽然说人家4g也菜,但是人家...

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

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

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

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

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

发表评论

访客

看不清,换一张

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