feed流拉取。读扩散

1,778 阅读4分钟

什么是feeed流典型业务

回答 微博 微信朋友圈 pinterest 是典型的feed流业务。因为系统的每一条消息就是一个feed 这类业务的特点是:

  1. 有好友关系 例如关注,粉丝
  2. 我们的主页由别人发布的feed组成 这类业务的典型动作是
  3. 关注,取关
  4. 发布feed
  5. 拉取自己的主业的feed流

这类业务的核心元素是:

  • 关系数据
  • feed数据

feed流的"拉取"与"推送"实现 是怎么回事儿

某feed系统中有 ABCD四个用户,其中: A关注bc,D关注B

发布一条feed流程简单 。

此时只需往c的feed队列里加入一条feed即可。

在拉模式中,取消关注的流程也比较简单。A取消关注C 此时只需要在A关注表删除C 并且在C粉丝表中删除A

拉模式 A获取别人发布的feed组成的主页 过程比较复杂

1 获取A关注列表 获取所关注用户发布的feed 对消息进行rank排序。分页取出对应的一页feeds

feed流拉模式(读扩散)有什么优点 优点:

  • 存储结构简单,数据存储量小,关系数据与feed数据只存一份
  • 取消关注 发布feed流程简单
  • 适合 早起用户量 数据量并发量不大时快速实现 缺点
  • 拉取朋友圈feed流流程复杂
  • 有多次数据访问 并且需要内存计算

系统通知

广义系统通知 有1对1通知,以及1都对多通知。

很多业务有这类技术通知,通知结果针对你。这类通知是推送,还是拉取呢。

登录微博时,会有一个计数的拉取,对网页端计数进行初始化 int getCountByType(int countType) 在浏览微博过程中,有人加你为好友,服务端对网页进行实时推送。搞成增加一个1个

系统对多的通知

QQ右下角弹窗广告 QQ登录页面新闻

同一天 用户登录弹出的新闻相同。不同天则不同 假设有一个表存放弹框新闻 t_msg(msg_id, date, msg_content) 有一个表存放用户信息 t_user(user_id, user_info, …) 有一个表来存放用户收到的新闻弹窗: t_user_msg(user_id, msg_id, date)

明显不能用推送方式 将t_user_msg对于所有user_id 改为拉取

如果改为拉取的方式会好很多: 在user每天第一次登陆时,将当天的msg_id拉取出来,并插入t_user_msg,表示已读 在user每天非第一次登陆时,则会插入t_user_msg失败,则说明已读,不再进行二次弹窗展现 这个方式虽然有所优化,但t_user_msg的数据量依然很大。

群聊 如果是推送 1条消息变为500条,系统压力会比较大 拉取 消息实时性如何保证

核心问题 群消息 只存一份还是每个成员存一份 答 存一份

群消息已读回执 是推还是拉?

如果群消息只存1份。如何知道每个成员读了哪些信息 可以利用群消息的偏序关系,记录每个EQpig远端lask_ack_msgid 。群内的每一个用户 只需要 群消息表:记录群消息 group_msgs(msgid,gid,sender_uid,timee,content) 各个字段的含义为 群id,群成员id,群成员最后收到的一条群id

一个群有A uid,uid2 uid3四名成员 整个消息的发送流程

A发出群消息 2 server收到消息后 将群消息落地 查询群有哪些成员 推送 3 对群成员 查询在线状态 4 对在线成员 实时推送

各个收到消息后 修改群成员lask——ack_msgid 告诉系统 这一条消息收到了

已读回执流程 对于每条消息有多少人已读多少人维度 需要基础表

40个用户在线 40消息推送给群友 40ack修改 last_ack_msgid 发送服务端 40已读回执 通知发送方 消息风暴扩散系数非常多大 储存40条ack

每个群消息都进行ack么。批量ack 累计收到N条群消息 再向服务端发送一次last——ack_msgid 发送方每一条消息 40个已读回执。 1分钟一次 也就60个请求

参考 www.cnblogs.com/liuqiyun/p/… 参考 mp.weixin.qq.com/s?__biz=MjM…