一、什么是Feed流?
Feed流就是能够实时/智能推送消息的数据流,如微博、朋友圈、动态等都属于Feed流。
Feed流有几个重要的概念:
- Feed:每一条消息都是一个Feed,如微博中的每一条微博等
- Feed流:多个Feed组成一个Feed流,如微博关注页、微信朋友圈等
- Timeline:即按照发布时间排序的Feed流,如微信朋友圈等(不按照推荐逻辑)
- Rank:即按照智能推荐排序的Feed流,如微博推荐页等
二、如何设计一个动态Feed流系统?
1、初始化
一开始用户还没有对应的Feed流的时候,我们就应该创建一个,如微博关注页,具体通过MySQL+Redis实现即可。
用关系型数据库MySQL就能完成了为什么还要用Redis呢?因为Feed流的场景是读多写少的,如果查询性能比较差,会很大程度影响用户体验的。
而Redis我们可以使用Zset数据结构来做,因为它是一个有序集合,可以按照我们的排序规则进行排序,如:
- key值:存当前用户id
- member值:存消息id
- score值:存消息id和对应的发布时间/权重
2、推送时机
Feed流是会更新的,所以我们要考虑每一个推送时机,具体如下:
- 用户关注
- 用户取消关注
- 关注的用户发动态
- 关注的用户删动态
- …
3、推送模式
Feed流的推送模式主要包括三种:
- 推模式:即主动推,如用户发了一条动态,那么会给所有关注他的用户都退一条Feed,这样的缺点是数据量太大(如果有千万个粉丝,则需要推千万条Feed)
- 拉模式:即被动拉,如用户发了一条动态,我们并不会做什么措施,而是等关注他的用户拉取关注页时再实时去查询,这样的缺点就是查询速度慢、聚合复杂(可以考虑使用es查询)
- 推拉结合模式:主要针对大V场景(粉丝量大),我们需要先区分哪些用户是大V(比如粉丝量超过100w),然后当用户发动态时,先判断是否为大V,如果是的话则用拉模式,如果不是的话则用推模式
4、推送步骤
当用户发布一条动态:
- 判断该用户是否大V,如果是则不做后续处理
- 如果是普通用户,则将该条Feed发送给该用户的粉丝的Feed流
当用户刷新关注页:
- 拉取自己的Feed流
- 查询自己关注的大V列表,并发拉取他们的动态Timeline
- 合并步骤1和步骤2的结果返回
三、Q&A
1、如果用推拉结合模式的话,可能会导致大V的动态Timeline读压力过大,要怎么解决呢?
我们知道粉丝也分为活跃粉和非活跃粉,那么我们针对这个做处理可以吗?
比如当大V发了一条动态,我们只需要对活跃粉采用推模式,而对非活跃粉采用拉模式,这样就能避免所有的用户都过来拉而导致读压力过大。(缺点可能是我们要多加判断活跃粉)