动态消息流是一个在你个人主页不同更定的故事列表,推特、mega和Instagram 的post消息都是典型的动态消息列表,和普通消息流系统的最大区别是消息流动态变化、实时更新
,设计一个动态消息系统核心功能消息流的构建和消息的发布,需要考虑的主要两个问题在于对于超大粉丝用户用户快速发布自己的消息和一个用户如何低延迟实时获取最新消息流,系统架构图如下。
news feed service:存储和查询用户发送的post
post DB:记录post的原数据,比如post内容,对外开放权限,开发人群。
fanout Service:根据post和粉丝列表生成news feed服务,因为一个用户发送一个post就要将对应所有好友的new Feed进行更新,有一个放大的过程,可以使用消息队列进行缓冲。
new Feed Cache:为了提高new Feed的查询效率,将生成的news Feed保存的缓存中,为了能够缓存更多的内容,只缓存userId和 postId
需要注意的点
1、对于单个用户来说,为了能够缩短自己查看内容的RT,当自己正在follewing的人创建一个post,应该在自己的feed流中插入一条post,对于有千万粉丝的大V来说,当自己发送一条post的时候,为了能够快速对所有自己关注的用户生成一个post,需要做热key处理吗,还是多线程就可以处理。
生成new feed的流的方式有两种:第一种是在用户生成post的时候,在对应好友的News feed流中插入,也称为push模式,粉丝在获取消息流时速度更快;另外一种是,用户在查看自己的news feed流的时候,根据自己关注人和他们发送的post实时生成,也称为pull模式,不会对fanout服务造成流量压力,出现hotkey问题。实际场景中,可以融合两种方式的优点,根据用户粉丝数量采取不同new feed发布方式。
针对极端场景,例如一个用户关注100w人,这100w人都是大v,实时生成自己的new feed流需要大量的过滤和计算,确实会比较耗时,可以考虑加入缓存、采取预生成策略和分页查询,会一定程度增加系统整体复杂度。
2、如果一个人新关注了一个朋友,需要将朋友历史已经发送的post都插入到自己的feed流吗?
为了控制数量,可以将关注朋友最新的N个post插入到自己的new feed中。
3、如果只是单纯的的查询自己的粉丝用户列表,需要使用Graph DB吗,查询速度就比mysql快吗?
只是查询粉丝列表,mysql就足够了,并且查询速度会很快