imekaku's blog thinking reading about

关注推荐Feed流


10 Feb 2019 - architecture

关注推荐服务

与推荐feed流有所不同,关注推荐服务所用到的视频池是根据用户的关注列表得到的,而不像feed流,使用的是整个的媒资库的视频池。

app实现的关注推荐feed类似于新浪微博的时间流乱序列表,但是根据业务场景又有所不同。


关注列表视频池存储方式

APP用户关注不同的up,up下有众多生产的视频,用户从而有一个关注池。

用户获取关注池的方式无非有两种:pull模式,push模式。

详尽的两种方式的介绍网上有很多,我发现有几篇文章写得很不错、易懂的,如下:

我采用的是使用推的模式。

即当up生成出的视频通过了审核被允许加入到用户的关注列表之后,这则视频将会进入up所有粉丝的关注列表。当一则视频被up或者运营审核人员删除之后,会从up的所有粉丝之中移除。


关注推荐服务架构

关注推荐服务架构图

存储与存储逻辑

存储方面主要有四个库:关注池落地库MySQL,红点库redis,关注推荐结果库redis,用户关系库redis

1. 落地MySQL库

MySQL中存储的是用户的关注的视频,其中某一个用户的关注池的一条视频就是MySQL中的一条记录。

落地库记录的是全量的视频记录,所以用户的新增关注、取消关注、视频被删除、视频隐私状态被改变、关注的up的视频新增都会反映到落地库中。即使没有其他三个库,用户也是可以获取到自己的关注列表的,但是是完全顺序的,如果不考虑红点等业务场景的话,这样一个库就能够满足需求了。

因为是全量库,所以如果有10w用户,每个人都关注池里有100条视频,那么MySQL中就会有1000w条记录。并且随着用户的新增,视频的新增,这个数目还会不断的累积。而且如果一个大V发布了一条视频,他拥有10w粉丝,那么发布这条视频的同时,就会产生10w条记录,这会带来数据库写突增的问题,以及数据库冗余数据存储的问题。

解决发布为:


2. 红点库redis

这边有一个业务逻辑是,需要将红点的视频放在关注列表的前面,并且这个优先级高于rank排序,并且当再次访问时关注列表时,顺序依旧不被改变。

所以当新视频进入关注池时,会被加入到红点池(落地库MySQL只要有关注列表更新都会更新);当一个视频被删除,up被取消关注导致视频被移出关注池,会被移出红点库。

3. 关注推荐结果库redis

这个库存储经过排序关注列表,起到一个分页的效果,并且保证红点池的视频能够排在之前的视频前面。当一个视频被删除,up被取消关注导致视频被移出关注池,也会被移出结果库。

4. 用户关系库redis

用户关系库主要存储用户与up的互动关系,其中有用户对up的互动详细数据,在排序阶段从这个库获取数据,并且计算视频得分,进行打分排序。


Extra

需要注意的是,由于留存率的原因,大部分用户来过平台之后,就不会再来,但是还是会为他保留这四个库其实是存在很大浪费的。

其中可以使用一些方法,减少浪费。

比如推荐结果库设置一定的失效时间,用户长久不更新结果库,那么会失效,当用户再次请求的时候,会直接从落地的全量MySQL库拉取数据,并且删除红点库对应的数据。

红点库也是浪费的主力,在往红点库新增数据的时候,可以检查一遍结果库是否有值,如果无值那么就没有必要更新。因为结果库无值,用户请求时,也不会需要红点库等数据。