系统设计 Feed 流
本文将探讨 Feed 流的系统设计。
一、什么是 Feed 流?
Feed 流,持续更新的信息流。
常见的 Feed 流产品有微博、微信朋友圈等。
二、特点
- 每个用户都可以发布内容,即每个用户都是 Feed 的生产者
- 用户看到的 Feed 流,应该是由其关注的所有账号发布的所有 Feed 聚合而成
- 用户与用户之间的关系并不稳定,关注、取关等操作时长发生
- 更多浏览更少发布,读多写少
三、实现 - 存储
1. 账号关系
账号关系存在以下特点:
- 数据量巨大
- 查询条件简单
可以考虑选用分布式 NoSQL 数据库,提升查询速度的同时方便分布式存储。
2. 文件
文件存储采用对象存储,它的数据结构为 K-V 形式,利于海量文件存储。
图片、视频在客户端上传前、服务器保存前都应该做压缩,在保证其质量的前提下节省存储空间。
考虑到不同用户可能会上传同一份热点文件,可以在上传前计算 Hash 判重,避免重复存储。
如果希望最大化上传速度,可以考虑在用户编辑时预先上传,从而加快发布速度。为避免用户编辑时 “先选中后去除” 等操作导致错误上传无用文件,应该采用策略对无用文件进行清理。
考虑到 Feed 浏览次数与时间的强相关性,可以配置文件的 “沉降规则”,将长时间未被访问的文件沉降至低频存储,降低存储成本。
四、实现 - 同步
1. 推模式
在数据库中,为每名用户维护一个 Feed 流列表。当有用户发布 Feed 时,将该 Feed 推送到其所有粉丝的 Feed 流列表中。这样以来,当用户想要浏览 Feed 流时,只需要查询列表即可。
特点:
- 如果某个用户是 “大 V”,一旦他发布 Feed,需要在数据库中插入成千上万条记录,数据库压力非常大
- 如果用户为 “僵尸用户”,列表的维护将毫无意义
- 因为要额外维护一个 Feed 流列表,因此需要的存储空间更大
2. 拉模式
当用户想要浏览 Feed 流时,查询所有关注的人的 Feed,排序组装为 Feed 流。
特点:
- 如果用户关注了大量账号,查询、组装的消耗将会非常大
- Feed 流在用户请求时才开始组装,速度慢,用户体验不佳
3. 推拉结合
- 对于 “大 V” 用户,采用拉;否则,采用推
- 若用户在线,采用推;否则,待用户上线后先采用拉构建列表,然后采用推