feed流系统的设计

什么是feed流系统

feed是将用户主动订阅的若干消息源组合在一起形成内容聚合器,帮助用户持续地获取最新的订阅源内容。

有哪些明显的feed流的:

  • 最早的 RSS(简易信息聚合),可以将其他多个网站的内容聚合到一起统一阅读。
  • 好友动态(微博、朋友圈)
  • feed变种(私信、通知、群聊)
  • 个性化推荐(抖音、头条)
  • 个人首页的历史消息
  • APP上消息红点数量或显示最后一条消息

feed流系统特点

Feed流本质上是一个数据流,是将 N个发布者的信息单元通过关注关系传送给M个接收者。通常接受者只需在自己的界面上即可看到所有推送的消息。

  • 发布者:产生数据
  • 关系:关系按开放程度不同可分为:全开放(抖音)、部分开放(群组)、单项关注(微博)、双向关注(微信)。不管关系如何,数据流永远是单向的。
  • 接受者:组织并接受数据

在设计feed流系统时,需要考虑的因数有:

  • 关系的开放程度:如果是单向关注,那么就会存在大v号,大v号在发消息时,消息处理通常时效性较差(分钟级)。反之双向关注,一般都会有好友数量限制,消息处理的时效性一般很高(秒级)
  • 排序:一般采用时间排序(发布时间、回复时间),或者推荐系统(rank权重、个性化推荐)。

消息流的存储与推送

储存

feed流系统,发布者产生的数据是随着用户量与时间增长而增长,关系也会随着用户量与时间增长而增长。所以储存需要考虑大量数据储存问题。这主要考虑:关系的储存、Feed消息的储存。在做数据库设计时,需考虑水平扩展能力。

消息推送

系统规模和产品类型,以及存储系统确定后,我们可以确定同步方式,常见的方式有三种:

  • 推模式(也叫写扩散):和名字一样,就是一种推的方式,发送者发送了一个消息后,立即将这个消息推送给接收者,但是接收者此时不一定在线,那么就需要有一个地方存储这个数据,这个存储的地方我们称为:同步库。推模式也叫写扩散的原因是,一个消息需要发送个多个粉丝,那么这条消息就会复制多份,写放大,所以也叫写扩散。这种模式下,对同步库的要求就是写入能力极强和稳定。读取的时候因为消息已经发到接收者的收件箱了,只需要读一次自己的收件箱即可,读请求的量极小,所以对读的QPS需求不大。归纳下,推模式中对同步库的要求只有一个:写入能力强。

  • 拉模式(也叫读扩散):这种是一种拉的方式,发送者发送了一条消息后,这条消息不会立即推送给粉丝,而是写入自己的发件箱,当粉丝上线后再去自己关注者的发件箱里面去读取,一条消息的写入只有一次,但是读取最多会和粉丝数一样,读会放大,所以也叫读扩散。拉模式的读写比例刚好和写扩散相反,那么对系统的要求是:读取能力强。另外这里还有一个误区,很多人在最开始设计feed流系统时,首先想到的是拉模式,因为这种和用户的使用体感是一样的,但是在系统设计上这种方式有不少痛点,最大的是每个粉丝需要记录自己上次读到了关注者的哪条消息,如果有1000个关注者,那么这个人需要记录1000个位置信息,这个量和关注量成正比的,远比用户数要大的多,这里要特别注意,虽然在产品前期数据量少的时候这种方式可以应付,但是量大了后就会事倍功半,得不偿失,切记切记。

  • 推拉结合模式:推模式在单向关系中,因为存在大V,那么一条消息可能会扩散几百万次,但是这些用户中可能有一半多是僵尸,永远不会上线,那么就存在资源浪费。而拉模式下,在系统架构上会很复杂,同时需要记录的位置信息是天量,不好解决,尤其是用户量多了后会成为第一个故障点。基于此,所以有了推拉结合模式。主要处理有如下几种:1、活跃用户使用推模式,不活跃的等其上线时使用拉模式,需要维护一个活跃用户表;2、大部分用户的消息都是推模式,只有大V是拉模式,需定义多少个关注算大v,同时返回结果时需要将推的数据与拉的数据整合。

Mysql业务实现

涉及的数据表如下:

  • 用户表(uid,nickname...)
  • Feed消息表(msg_id,uid,content,time,...) 消息之储存一份
  • 用户关系表(uid,to_uid,time,...)
  • 同步表(uid发送者, to_uid接受者, msg_id消息id, ...) 推送给别人的只给msg_id即可

具体业务说明:

  • 通常在客户端维护一个最后读取时间字段,可以标记当前用户读到哪里了,或者请求时提交此字段,只返回新消息。
  • 可以在同步表中维护一个是否已读字段,标记当前消息是否已被度过,通常用在消息系统中。
  • 根据具体业务不同,同步库的存在形式也不同。例如在红点数需求时,同步表信息可以写入消息队列,客户端接受到消息后,计数+1,后端销毁此数据。或者显示“已有新消息”提示刷新查看。
  • 对于类似抖音这种,无用户关系的产品,我们可以理解成关注了所有用户。它会根据我们的行为判断喜好,从而构建同步表。

此处评论已关闭