阿里面试官:使用Redis手写个feed流

2,403 阅读4分钟

1 简介

朋友圈,微博,都是 Feed 流产品,还有图片分享网站 Pinterest,花瓣网等又是另一种形式的 Feed 流产品。很多 App 也都会有一个模块,叫动态或消息广场,这些也是 Feed 流产品。

核心概念

  • Feed Feed 流中的每一条状态或者消息。比如朋友圈中的一个状态就是一个 Feed,微博中的一条微博就是一个 Feed。
  • Feed 流 持续更新并呈现给用户内容的信息流。每个人的朋友圈,微博关注页等等都是一个 Feed 流。
  • Timeline Feed 流的一种,微博,朋友圈都是 Timeline 类型的 Feed 流,但由于 Timeline 类型出现最早,使用最广泛,最为人熟知,有时也用 Timeline 表示 Feed 流。
  • 关注页 Timeline 展示其他人 Feed 消息的页面,比如朋友圈,微博首页。
  • 个人页 Timeline 展示自己发送过的 Feed 消息的页面,比如微信中的相册,微博的个人页。

2 特点

  • 多账号内容流 Feed 流系统中肯定会存在成千上万的账号,账号之间可以关注,取关,加好友和拉黑等操作。只要满足这一条,那么就可以当做 Feed 流系统来设计。
  • 非稳定的账号关系 由于存在关注,取关等操作,所以系统中的用户之间的关系就会一直在变化,是一种非稳定的状态。
  • 读写比例 100:1 读写严重不平衡,读多写少,一般读写比例在 10:1,甚至 100:1 以上。
  • 消息必达性要求高 比如发送了一条朋友圈后,结果部分朋友看到了,部分朋友没看到,如果偏偏女朋友没看到,那么可能会产生很严重的感情矛盾,后果很严重。

3 分类

  • Timeline 按发布的时间顺序排序,先发布的先看到,后发布的排列在最顶端,类似于微信朋友圈,微博等。这也是一种最常见的形式。产品如果选择 Timeline 类型,那么就是认为Feed流中的Feed不多,但是每个Feed都很重要,都需要用户看到。
  • Rank 按某个非时间的因子排序,一般是按照用户的喜好度排序,用户最喜欢的排在最前面,次喜欢的排在后面。这种一般假定用户可能看到的 Feed 非常多,而用户花费在这里的时间有限,那么就为用户选择出用户最想看的 Top N 结果,场景的应用场景有图片分享、新闻推荐类、商品推荐等。

4 难点

4.1 存储

因为该项目中 Feed 比较简单,就类比于空间说说,因此可以使用 MySQL存储,如果对于数据结构比较复杂的 Feed 流就要使用 NoSQL 数据库,这样存储更方便与高效,比如 MongoDB 或 HBase。

4.2 推送

在推送方案里面的,有三种方案,分别是:

拉模式

也称为读扩散,用户主动去拉取关注人的 Feed 内容。 即当一个用户(特别是关注了很多人)触发行为时,拉取自己动态,检索用户的关注表,然后根据关注表检索新发的feed。如果一个用户关注过多的时候,查询该用户的关注列表也是有很大数据成本。

推模式

也成为写扩散,当用户添加 Feed 时,会自动将 Feed 通知给关注的人(优选)。 即当一个用户触发行为(比如发微博),自身行为记录到行为表中,同时也对应到这个用户的粉丝表,为每个粉丝插入一条feed。但是对于粉丝过万的大V,为每个粉丝插入一条feed对存储数据成本很大。

使用 Redis Sorted Sets(方便按时间排序 Timeline)维护粉丝的 Feed 集合,当博主添加 Feed 时,主动将内容推送到粉丝的 Feed 集合中,这样用户可以很方便快速从集合中读取

推拉结合

比如微博,大部分用户的账号关系都是几百个,但是有个别用户是 1000 万以上才使用。

在线推,离线拉

  • 大V发动态,只同步发布动态给同时在线的粉丝,离线的粉丝上线后,再去拉取动态。来完成推与拉。

定时推,离线拉

大V发动态之后,以常驻进程的方式定时推送到粉丝动态表。

5 表设计

参考