微博Feed流读扩散设计
参考主要来自58沈剑←
[知识整理]根据个人理解整理后分享,请批判接受,有误请指正。转载请注明出处:
https://heyfl.gitee.io/design/Weibo-feed-design.html
什么是Feed流
Feed流即持续更新并呈现给用户内容的信息流 , 对于微博.微信朋友圈等业务刷新的数据都为Feed流
每条微博 朋友圈 为一条Feed
关键动作,关键数据
关键动作
- 关注 , 取关
- 发布Feed(朋友圈or微博)
- 获取自己主页的Feed流
核心数据
- 关系数据
- Feed数据
难点
自己的主页由他人的Feed流组成
如果大家都是读写同一条Feed,会出现较大的读写冲突 造成系统的主要瓶颈
获取Feed流解决方案
模式有2种类:
- 拉模式
- 推模式
拉取模式
大致的数据结构
用户关系
- 用户的关注关系 user_follow(id,uid,follow_id…)
- 用户的粉丝关系 user_fans(id,uid,fans_id) //之所以要分成正反表是为了大数据量高并发情况下 可以做到分库
用户的消息列表(Feed)
用户发出的消息 user_msg(msg_id,uid,create_tm…)
流程
消息发布流程
用户A发出消息,只需要在[user_msg]表里插入一条消息
关注&取关流程
以用户A取消关注用户B为例:
- 在A的关注列表里 删除B的记录
- 在B的粉丝列表里 删除A的记录
这里关注表和粉丝表不在同个库 但是不需要用到分布式事务, 用最终一致性就可以保证业务需求了
获取用户A主页的Feed流流程
- [拉列表]获取用户A的所有的关注列表followList
- [通过列表再拉列表]遍历followList,获取所有被关注人发的所有消息的集合msgList (当然 这里得limit一下)
- [汇总排序]对每个msgList进行汇总排序 (这里可以利用最大堆把2,3合在一起)
优点:
- 存储结构简单,数据存储量较小,关系数据与feed数据都只存一份
- 取消关注,发布feed的业务流程非常简单
- 存储结构,业务流程都比较容易理解,非常适合项目早期用户量、数据量、并发量不大时的快速实现
缺点:
- 拉取朋友圈feed流列表的业务流程非常复杂
- 有多次数据访问,并且要进行大量的内存计算,大量数据的网络传输,性能较低
在拉模式中,系统的瓶颈容易出现在“用户所发布feed列表”的读取上,而每个用户发布feed的频率其实是很低的;
此时,架构优化的核心是通过缓存降低数据存储磁盘IO