上一篇《feed流拉取,读扩散,究竟是啥?》关于feed流的拉取还是推送,只写了一半“拉取”,今天把另一半“推送”(写扩散)的坑填完。
为了对比“拉”“推”两种方案,同时也为了避免大伙在两篇文章切换,故先简单赘述背景与“拉”(读扩散)方案。
feed业务特点:有类似于“关注/粉丝”的好友关系,个人的主页由别人发布的feed消息组成。
feed业务典型动作:关注,取关,发布feed,拉取自己的主页feed流。
feed业务核心数据:关系数据,feed数据。
一、拉模式 “读扩散”方案简介
例如,某feed系统里有ABCD四个用户,其中:
其关系存储又包含关注关系与粉丝关系,“A关注了BC,D关注了B”的潜台词是“B有两个粉丝AD,C有一个粉丝A”。
每一个用户,都有一个feed队列,记录自己曾经发布的所有feed数据。
在拉模式中,发布一条feed的流程非常简单,例如C新发布了一条msg12:
此时只需往C的feed队列里加入一条feed即可。
在拉模式中,取消关注的流程也非常简单,例如A取消关注C:
此时只需要在A的关注列表里删除C,并在C的粉丝列表里删除A即可。
在拉模式中,用户A获取“由别人发布的feed组成的主页”的过程及其复杂,此时需要:
feed流的拉模式(“读扩散”)的优点是:
缺点也显而易见:
二、推模式 “写扩散”方案简介
推模式(写扩散),关系数据的存储与拉模式(读扩散)完全一样。
feed数据,每个用户也存储自己发布的feed。
如上图:
画外音:不妨设,这里的msgid按照feed的发布时间偏序。
feed数据存储,与拉(读扩散)不同的是,每个用户还需要存储自己收到的feed流。
如上图:
在推模式(写扩散)中,获取“由别人发布的feed组成的主页”会变得异常简单,假设一页消息为3条feed,A如果要看自己朋友圈的第二页消息,直接返回1,2,3即可。
画外音:第一页朋友圈是最新的消息,即5,8,10。
在推模式(写扩散)中,发布一条feed的流程会更复杂一点。
例如B新发布了一条msg12:
之所以该方案称为推模式(写扩散),就是因为,用户发布feed的时候:
在推模式(写扩散)中,添加关注的流程也会变得复杂。
例如D新增关注C:
画外音:有些产品有这样的逻辑,“关注之后才能看到feed”,这样的话就不需要第三步,旧feed无需插入。
在推模式(写扩散)中,取消关注的流程也会变得复杂。
例如A取消关注C:
feed流的推模式(写扩散)的优点是:
画外音:拉模式(读扩散)中,用户发布feed存储容易称为IO瓶颈。
画外音:feed业务是典型的读多写少业务场景,读写比甚至高于100:1,即平均发布1条消息,有至少100次阅读。
其缺点是:
画外音:有朋友提出,可以存储一份消息实体,只冗余msgid,这样的话,拉取feed流列表时,还要再次拉取实体,网络时延会更长,所以很多公司选择直接冗余消息实体,当然,这是一个用户体验与存储量的折衷设计。
三、小结
feed流业务的推拉模式小结:
另外,大幂幂5KW粉丝,她每次一发博文,消息会冗余5KW份消息,如何进行优化?推拉结合的方式又是如何实施的?欢迎大家讨论。