Feed流系统

Feed流系统 #

业务概述 #

角色模型

  • 创作者(Followee):又称被关注者、Up、博主等。创作者可以发表信息(推文、博客)。
  • 关注者(Follower):又称粉丝。关注者可以同时关注多个创作者。用户可以兼具创作者和关注者。

主要功能

  • 创作者发布信息。
  • 关注者关注/取关创作者。
  • Feed流展示:用户主页展示关注的所有创作者的最新信息。Feed流可以是单纯基于时间的Timeline流,也可以是基于权重的Rank流,还可以是两者的结合。

数据建模 #

表结构

  • Feed表:信息ID、创建人ID、创建时间、信息内容、信息状态。
    • 信息ID包含创建时间(时间戳+递增序号)时可以省去额外的按时间排序。
    • 分区方案:
      • 信息ID:用户发布的信息可能保存在多个节点上,查询时需要跨区。
      • 用户ID:用户发布的信息保存在单个节点上,可能分布不均,存在热点问题。极端情况下一个节点可能无法容纳单个用户的数据。

缓存方案

  • 用户关系缓存:key=用户ID,field=用户关注的创作者IDs,value=创作者信息。
  • 最新信息缓存:key=用户ID,value=信息IDs。用于为活跃用户缓存过去五天发布的推文,
  • 收件箱缓存:当消息发布采用写扩散时,用来保存在线用户的数据,加速信息的获取速度。

消息处理模式 #

  • 拉模式(读扩散):创作者在发布信息时写入自己的发件箱,关注者展示Feed流时需要从所有关注的人那里获得新信息后进行聚合。
  • 推模式(写扩散):创作者在发布信息时写入所有关注者的收件箱。关注者通过自己的收件箱构建Feed流。有多少关注者,消息就需要保存多份,推送多次,所以写扩散时需要使用队列进行削峰。
  • 混合模式:
    • 按创作者的关注用户数区别处理,粉丝少采用写扩散,粉丝多则采用读扩散。
    • 按用户是否在线区别处理,在线用户采用写扩散,离线用户采用读扩散。

生成Timeline型的Feed流 #

业务需求

  • 显示当前用户关注的所有创作者的最新信息,按时间线倒序排列。
  • 用户可以将关注的人进行分组,每个分组都有单独的Timeline。
  • 当一个创作者删除某条信息后,关注他的用户应该看不到这条信息。
  • 当一个用户取消关注某个创作者后,该用户就应该看不到该创作者的所有信息。

拉模式

  1. 创作者发布信息时写入收件箱和最新信息缓存。
  2. 从用户关系缓存中获取当前用户关注的所有创作者的ID。
  3. 根据创作者ID在最新信息缓存中找出所有匹配的信息。
  4. 在应用层面对信息ID集合进行聚合。
  5. 过滤掉已被删除的信息以及取关的创作者所创建的信息。

推模式

  1. 创作者发布信息时写入消息队列,广播到关注者的收件箱。
  2. 用户登录后从收件箱中取出所有信息进行排序。
  3. 过滤掉已被删除的信息以及取关的创作者所创建的信息。

基于上线状态的推拉集合模式

  1. 创建者发布信息时写入收件箱、最新信息缓存、在线用户的收件箱缓存。
  2. 检查收件箱缓存,没有数据时再使用拉模式进行聚合。

未读信息数方案 #

  • offset:用户只存储最后一条已读消息的offset。适合IM聊天等场景。
  • bitmap映射:将用户ID映射到bitmap上,已读设为1,未读设为0。适合需要知道消息是否已读的场景,如系统通知等。
  • 差集对比:适合只需显示未读信息数,且数据规模大的场景。
    1. 在缓存中记录关注的所有创作者的信息数,key=用户ID,hashKey=关注的创作者ID,value=count,value为信息数。
    2. 生成Feed流时,记录用户当前关注的所有创作者的信息数。
    3. 未读信息数 = 用户当前关注的所有人的信息数 - 快照中的信息数。
    4. 用户点击未读消息后,将用户当前关注的信息数刷新到快照中。
沪ICP备17055033号-2