系统设计 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” 用户,采用拉;否则,采用推
  • 若用户在线,采用推;否则,待用户上线后先采用拉构建列表,然后采用推

参考