简单方案
Select * from post where user_id in (following_userId_list) order by publish_time desc;
短时间内还可以维持一段时间,当数据量达到千级别,数据库查询可能会出性能问题。
优点:该方案简单,容易开发迅速上线,适合非常前期的使用。
缺点:不能支撑后续比较大的数据量
推拉模式结合
整体思路
- 用户发布帖子
- 获取粉丝列表和活跃用户列表,取活跃的粉丝用户,采用推的模式将帖子数据推给粉丝。
- 粉丝维护自己的feed列表
- 非活跃用户采用拉的方式拉取关注用户的帖子按照时间的顺序加入到用户的feed列表。
推数据
用户发布帖子,统计出用户的粉丝列表,通过消息队列发送消息。收到消息去维护每个用户的feed列表。如果粉丝用户比较多,可以采用分块的形式去发送,比如一条消息附带100个用户id。如果粉丝比较多有1000万,考虑到有很多僵尸用户,纯采用推的模式会浪费性能和存储空间。所以结合拉的模式一起使用。只推给活跃用户,非活跃用户采用拉的模式获取数据。
活跃用户列表
需要客户端配合,将正在浏览app的用户发送到后端。后端可以用redis去存储活跃用户列表。
非活跃用户,登陆时会变成活跃用户,这个时候要去异步拉取其关注的博主的帖子列表存到自己的feed流中。为什么要异步,因为这个过程还是比较耗时的,所以异步提前准备数据,当用户进入following页面时就可以看到数据了。
拉数据
非活跃用户登录时,进入活跃列表。同时触发异步拉取博主帖子数据。
用户feed列表
数据量少的时候可以使用mysql,也可以使用redis。使用redis的sortedset,使用发布时间作为分数。这样的缺点就是mysql性能差,redis贵。数据量少的时候都可以用,多了可以迁移到阿里云的TableStore存储。
数据存储方案
前期可以redis+mysql存储,后期数据量增长到更大的一个层级可以采用Hbase或者阿里云TableStore。
阿里云:如何打造千万级feed流系统
https://help.aliyun.com/document_detail/141820.html?spm=a2c4g.11186623.6.680.32356b9f8mxYsb