群消息,究竟存一份还是多份?

上一篇文章《群消息已读回执,究竟是推还是拉?》说,“很容易想到,是存一份”,被网友们骂了。

网友骂的对,任何技术方案,都不是天才般灵感乍现想到的,一定是一个演进迭代,逐步优化的过程。今天就聊一聊,群消息,为啥只需要存一份。

群信息,用户信息,群成员关系都是基础数据:

group_info(gid, group_info);

user_info(uid, user_info);

group_members(gid, uid);

假设一个群(gid)里有4个成员,其中三个在线(A, uid1, uid2),一个不在线(uid3)。

A发送了一条消息,很容易想到,对于不同的群友消息存多份,每个群友一个队列来存储。但由于在线的用户会实时的收到消息,所以暂定只为离线的用户存储

用户收到的群消息,也是基础数据:

user_msgs(uid,msgid,gid,sender_uid,time,content);

很容易想到,整个群消息的发送流程如上图1-4:

(1)发送消息

(2)查询状态

(3)不在线的存储离线

(4)在线的实时推送

“在线的群友不存储,离线的群友才存储”会带来的问题是,如果第四步发生异常,群友会丢失消息。

消息的可达性是聊天系统中最重要的要素(没有之一),故这个方案是不行的,需要优化为“不管是否在线,都要先存储”。

发送群消息的流程优化为,如上图1-4:

(1)发送消息

(2)所有人都存一份

(3)查询状态

(4)在线的实时推送

先将消息落地,能够保证消息可达性,那何时才能删除已经落地的群消息呢?

对于在线的群友,收到群消息后,给个ack确认,才能删除。

画外音:逻辑删除,还是物理删除,根据业务是否有消息漫游决定。

对于离线的群友,在下次登陆后,拉取完离线消息,再给ack确认,才能删除。

总之,为了保证消息的可达性,不管是在线消息,还是离线消息,必须接收方给ack确认,才能删除消息。

“不管是否在线,都冗余一份群消息”带来的问题是,同一条消息存储了很多次,对磁盘和带宽造成了很大的浪费。很容易想到的优化是:群消息实体存储一份,用户只冗余消息ID。

故基础数据可以由:

user_msgs(uid,msgid,gid,sender_uid,time,content);

优化为:

group_msgs(msgid,gid,sender_uid,time,content);

user_msgs(uid, msgid, gid);

这个优化,对于消息投递,以及消息删除的核心流程没有影响,几个实践为:

  • 在线用户投递消息实体,ack消息ID

  • 离线用户先拉取消息ID,再拉取消息实体,再ack消息ID

如此这般,假如在某个群友A期间,群里陆续发送了N条消息,则user_msgs(uid, msgid, gid)里,会有 uidA -> mid1,mid2, mid3, … midN 等N条离线记录,拉取离线消息时,可以把这N条消息一次性拉取出来,然后再删除:

delete from user_msgs

where msgid in($mid1,$mid2…, $midN) and gid=$gid

然而,群消息具备“偏序”特性,上面的一次性删除完全可以优化为:

delete from user_msgs

where msgid >= $mid1 and gid=$gid

这就意味着,每个用户只需要记录“最近一次收到的消息ID”,而不用记录“所有未收到的消息ID集合”,每当收在线消息ack,以及拉离线消息ack时,只需要更新这个“最近一次收到的消息ID”即可。

于是乎,基础数据可以由:

group_members(gid, uid);

group_msgs(msgid,gid,sender_uid,time,content);

user_msgs(uid, msgid, gid);

优化为:

group_members(gid, uid, last_ack_msgid);

group_msgs(msgid,gid,sender_uid,time,content);

user_msgs(uid, msgid, gid); // 不再需要

即,群消息只存储一份,群友无需冗余任何消息实体,或者消息ID了。

对于在线的群友,收到群消息后,修改这个last_ack_msgid。

对于离线的群友,拉取群消息后,也修改这个last_ack_msgid。

画外音:这里的讨论,仅限于接收方收到了哪些消息,和发送方的已读回执没有关系。

总结

任何架构方案都不是灵光一现,而是逐步迭代优化产生的:

  • 存多份,只存在线,消息容易丢

  • 存多份,所有群友都存储,消息冗余多

  • 存多份,只存ID,未利用偏序

  • 存一份,只存last_ack_msgid

架构不(只)是设计出来的,更是演进出来的。

挖坑篇:《feed流,单聊群聊,系统通知,状态同步,到底是推还是拉?》

填坑篇1:《系统通知,究竟是推还是拉?》

填坑篇2:《状态同步,究竟是推还是拉?》

填坑篇3:《网页端消息,究竟是推还是拉?》

填坑篇4:《群消息已读回执,究竟是推还是拉?》

码字不易,求转。

群消息,究竟存1份还是多份?相关推荐

  1. 狂宴终有尽时,留一份清醒一份醉 比特币现金BCH凸显投资价值

    市场波动率如期上升,强势币种进入加速冲顶阶段 本周BTC 8800至9700的核心箱体中窄幅震荡,正如BlockVC策略研究上周周报预期示,在大类币种震荡整理期间,炒作热点迅速扩散,各类题材及小市值币 ...

  2. 给2021金三银四的程序员们-投简历100份,1份面试通知都没收到,哪里出了问题

    与该岗位契合度 写好简历要重点把握住以下几个方面: 人职匹配.HR招聘.看简历的一个基本原则就是"人职"匹配,因此整个简历呈现出的你的知识.技能.能力等综合素质,要和个人应聘的职位 ...

  3. ThreadLocal究竟存不存在内存泄漏?

    写ThreadLocal原理的文章太多了,笔者这里不想再分析源码,也不想剖析其实现原理,其实也并不难,就直接说下ThreadLocal的原理吧. 1.ThreadLocal原理简介 假设定义了两个Th ...

  4. RigUp 数据库暴露7.6万份美国能源行业文件

     聚焦源代码安全,网罗国内外最新资讯! 编译:奇安信代码卫士团队 安全厂商 vpnMentor 发布报告称,美国能源行业劳力市场和服务提供商 RigUp 的一个 AWS S3 存储桶遭暴露,导致美国能 ...

  5. 前端HTML与CSS入门-一份媲美黑马培训班2万学费的知识干货

    前端HTML与CSS入门&移动端布局-媲美黑马培训班2万学费的知识干货 作者 | 苏察哈尔灿 声明 | 原创作品 转载需注明出处,并附跳转链接. 寄语| 愿我们一马平川 ,我的江湖有酒 ,有诗 ...

  6. 只用1分钟,搞定500份简历筛选!

    只用1分钟,搞定500份简历筛选!  柳姑娘黄海柳 6635人已订阅 订阅 文|黄海柳 做招聘,其实就是HR通过自己的专业领域,利用专业知识技能,为企业各个部门.各个岗位搜集并提供优质人才.输送&qu ...

  7. 如何在家写出一份无懈可击的产品文档

    www.pmcaff.com 本文为作者 我是仔仔侠 于社区发布 困在家里,每天起床 - 开早会 - 开项目会议 - 刷牙洗脸 - 看文档邮件 - 开项目会议 - 循环往复直至睡觉,不胖都难... 每 ...

  8. STM32U5来了,100份好礼免费送!

    大家好,我是张巧龙,全新超低功耗系列STM32U5生态圈上新了! 2021 年 10 月 11 日,意法半导体推出新的STM32Cube 软件包和开发工具以及评估板,加快使用最新的 STM32U5微控 ...

  9. 三个数相减的平方公式_快收好这份小学数学公式大全!孩子遇到数学难题时肯定用得上...

    必背定义.定理公式 1.三角形的面积=底×高÷2 公式 S= a×h÷2 2.正方形的面积=边长×边长 公式 S= a×a 3.长方形的面积=长×宽 公式 S= a×b 4.平行四边形的面积=底×高 ...

最新文章

  1. 阿里员工都是这样排查Java问题的,附工具单
  2. 敏捷需求分析及深度提升(广州 2014.1.11)- 活动报道
  3. 深入讲解Android Property机制
  4. 计算机网络IEEE 802,已连接到 IEEE 802.1 x 身份验证的计算机网络通过另一 802.1 x 启用的设备未连接到正确的网络...
  5. linux c ftp断点续传,求个支持断点续传的ftp脚本
  6. ios macos_设计师可以从iOS 14和macOS Big Sur中学到什么?
  7. mysql qt自增_mysql自增设置
  8. python得到列表list的交集与差集
  9. asp.net文件上传进度条控件(破解版~没有时间限制) 多项自定义
  10. [RMAN]控制文件的恢复
  11. python2.7初学(〇)
  12. NYOJ--60谁获得了最高奖学金
  13. 台式计算机 行业标准,GBT 9813.3-2017 计算机通用规范 第3部分:服务器国家标准...
  14. 最新emoji表情代码大全_抖音不用考虑我我没感受铁打的图片,最新表情包高清大全[多图]-软件教程...
  15. 100套计算机毕设源码+论文 免费分享 【2020最新版】
  16. 推荐几个好用的后台管理框架
  17. 下一代微型计算机,「简讯」GTX 1650完整规格曝光;任天堂推迟下一代Switch上市时间…...
  18. 【转载】生产订单完工确认(CO11N) BAPI : BAPI_PRODORDCONF_CREATE_TT
  19. android电梯程序设计,[源码和文档分享]基于Android实现的电梯调度模拟
  20. java实现根号n路归并排序

热门文章

  1. PDF转PPT其实很简单
  2. NPM 命令传递参数
  3. QT for Android环境配置犯病过程记录
  4. 为什么计算机专业叫宇宙机,有一说一 末流985天坑专业和宇宙机的差距真的蛮大的...
  5. 自动化专业与计算机专业的联系和区别,自动化专业与人工智能的关系
  6. 超次元大海战如何用电脑玩 超次元大海战手游PC电脑版教程
  7. 无法找到vcredist.msi
  8. Sentinel(四)限流算法-令牌桶算法
  9. Error:fatal error C1010: unexpected end of file while looking for precompiled head
  10. 炒菜机器人的弊端_一款饱受争议的炒菜机器人