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

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

卡卷网5个月前 (05-03)每日看点110

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亿粉丝,直播间10w的在线观看人数,日常带货随便一场也是上7位数的数据。现在抖音的市场好像已经被头部占领,资源靠前,普通人似乎已经没有机会了?下面是小杨哥对于做抖音的...

短视频如何快速变现?

短视频如何快速变现?

单人日产200条视频,一晚狂赚上千元,过程却简单到荒唐。只要你像这只猥琐的海鸥一样,做到这3点就行↓↓点开有惊喜速度快、不讲武德、不被发现那做短视频如何做到这3点?答案是养一只会叼视频的海鸥不是让你养真的海鸥而是用 ai 运营方法,类似于“...

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

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

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

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

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

为何 Linus 一个人就能写出这么强的系统,中国却做不出来?

为何 Linus 一个人就能写出这么强的系统,中国却做不出来?

我给你举个真实的例子。。有一个人叫高伟东,在哈尔滨工作。在2012年做了一个APP。使用词根词缀背单词。名字叫:词根词缀词典这个人编辑了2300余条词根,给10万多条单词建立了词根索引,整理了50多万条的单词记忆方法,包括新版本的诸多新功能...

是什么让你抛弃了 Windows 而转向 Mac?

是什么让你抛弃了 Windows 而转向 Mac?

别的不说,这玩意儿是真抗造啊,我这2012年买的MacBook Pro,依然在用……这台电脑我博士最后两年用来写代码(只写不运行,运行要上集群)和写论文,工作之后就变成生活和娱乐了,因为我一直用架子和外接键盘(颈椎不好)所以电脑看起来很新,...

发表评论

访客

看不清,换一张

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