Feed流

2020/12/28 SystemDesign 共 2089 字,约 6 分钟

Feed流

如何打造千万级Feed流系统

Feed设计总纲

概念

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

特征

Feed流系统有一些非常典型的特点,比如:

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

关注关系:

  • 关注关系是单向还是双向:
  • 如果是单向,那么可能就会存在大 V 效应,同时时效性可以低一些,比如到分钟级别;
  • 如果是双向,那就是好友,好友的数量有限,那么就不会有大 V,因为每个人的精力有限,他不可能主动加几千万的好友,这时候因为关系更精密,时效性要求会更高,需要都秒级别。

分类

Feed流的分类有很多种,但最常见的分类有两种:

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

上面两种是最典型,也是最常见的分类方式,另外的话,也有其他的分类标准,在其他的分类标准中的话,会多出两种类型:

  • Aggregate:聚合类型,比如好几个朋友都看了同一场电影,这个就可以聚合为一条Feed:A,B,C看了电影《你的名字》,这种聚合功能比较适合在客户端做。一般的Aggregate类型是Timeline类型 + 客户端聚合。
  • Notice:通知类型,这种其实已经是功能类型了,通知类型一般用于APP中的各种通知,私信等常见。这种也是Timeline类型,或者是Aggregate类型。

同步方式

推模式和拉模式对比

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

  • 拉方案:也称为读扩散。
  • 推方案:也成为写扩散。

对于拉方案和推方案,他们在很多方面完全相反,在看对比之前有一点要强调下:

  • 对Feed流产品的用户而言,刷新Feed流(读取)时候的延迟敏感度要远远大于发布(写入)的时候。

img

推模式的一个副作用

同上面的对比中可以明显看出来,推模式要远远比拉模式更好一些,但是也有一个缺点:

  • 数据会极大膨胀。

推拉结合

在单向关系中,因为存在大 V

  • 大V: 关注的大V采用拉模式,普通用户采用推模式
  • 第二种: 对活跃粉丝采用推模式,非活跃粉丝采用拉模式,应对大流量冲击

归纳下

  • 如果产品中是双向关系,那么就采用推模式。
  • 如果产品中是单向关系,且用户数少于 1000 万,那么也采用推模式,足够了。
  • 如果产品是单向关系,单用户数大于 1000 万,那么采用推拉结合模式,这时候可以从推模式演进过来,不需要额外重新推翻重做。
  • 永远不要只用拉模式。
  • 如果是一个初创企业,先用推模式,快速把系统设计出来,然后让产品去验证、迭代,等客户数大幅上涨到 1000 万后,再考虑升级为推拉集合模式。

存储

存储主要考虑关注关系以及Feed等。

对于关注关系:

  • 关注和取关对性能敏感,并且量级大。因此可以考虑有序性的NoSQL,比如HBase

对于个人列表,关注列表等:

  • 一个有序列表即可。关于有序列表可以参考图数据库设计

Model

Item: id, content, author, create_time

UserItemList: user_id, item_id, create_time

其他问题

删除一个feed怎么办

因为拉链都是存的id,id访问feed元数据时,看到已删除,异步删除即可,读时再更新。

Feed流里加广告

  1. 可以是一种虚拟的关注关系,比如关注了一个发广告的机器人,就进关注列表了
  2. 或者在拉Feed流时,随机插入广告

Feed流按推荐排序

一个Feed流队列,由推荐系统生成Feed流,用户不停scan,浏览后加到历史已读拉链里。

Search

    Table of Contents