即时消息技术剖析与实战
袁武林
微博研发中心技术专家
24187 人已学习
新⼈⾸单¥59
登录后,你可以任选4讲全文学习
课程目录
已完结/共 25 讲
即时消息技术剖析与实战
15
15
1.0x
00:00/00:00
登录|注册

20 | 存储和并发:万人群聊系统设计中的几个难点

网关机本地自治维护
针对离线消息接收端进行批量ACK
限速和丢弃离线消息
优化离线消息存储
合并变更方式
未读数存储资源压力
加入删除索引
记录用户加群信息
读扩散方式
点对点聊天 vs 群聊
不记录全局的在线状态
离线消息批量ACK
离线Buffer只存消息ID
未读数合并变更
单个用户删除消息处理
新加入群的用户只看到新消息
群聊消息存储
存储和并发:万人群聊系统设计中的几个难点

该思维导图由 AI 生成,仅供参考

你好,我是袁武林。
我在场景篇的第 10 讲“自动智能扩缩容:直播互动场景中峰值流量的应对”中,分析了直播互动场景中,容易出现瓶颈的原因主要在于:“直播间人数多,短时间内活跃度高,消息的扇出量巨大”。
那么,对于同样属于多人互动的群聊场景来说,虽然在“群人数”等方面与高热度的直播间相比要少一些,但由于同时开播的直播间数量一般不会太多,所以群在数量上的总体量级相对要大得多,可能上百万个群同时会有消息收发的情况发生。因此,在整体的流量方面,群聊场景的消息扇出也是非常大的。
而且和直播互动场景不太一样的是,直播互动中,热度高的直播活动持续时间都比较短,可以借助上云,来进行短时间的扩容解决,成本方面也比较可控;但群聊的场景,一般是流量总量高,但是峰值没有那么明显,靠扩容解决不太现实。因此,更多地需要我们从架构和设计层面来优化。
今天,我们就一起从架构设计层面,来聊一聊万人群聊系统中的几个难点,以及相应的解决方案。

群聊消息怎么存储?

首先来看一看群聊消息存储的问题。
关于点对点聊天场景,我在第 2 课“消息收发架构:为你的 App,加上实时通信功能”中也有讲到:我们在一条消息发出后,会针对消息收发的双方,各自存储一条索引,便于双方进行查询、删除、撤回等操作。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

万人群聊系统设计中的关键难点包括群聊消息存储、新用户加入群聊后如何只看到新消息、单个用户删除消息的处理、未读数合并变更以及离线Buffer的优化。针对这些难点,文章提出了一些解决方案,如采用“读扩散”方式进行群聊消息存储、记录用户加群信息以限制消息范围、采用合并变更方式降低未读资源的写入压力等。此外,还介绍了针对离线消息批量ACK和不记录全局在线状态的优化方案。这些方案具有普适性,可应用于其他有写入瓶颈的业务上。整体而言,本文深入探讨了万人群聊系统的架构优化,为读者提供了有价值的技术参考。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《即时消息技术剖析与实战》
新⼈⾸单¥59
立即购买
登录 后留言

全部留言(27)

  • 最新
  • 精选
  • clip
    思考题: 看情况考虑。 不好的地方: 所有网关机都要从消息队列消费这条数据,但最终只有一台机器处理,比较浪费处理资源。对这条消息而言本来可以直接下推,结果要多经过了网关机,实时性可能会受到大群的影响。 好的地方: 不过采用网关机方案可以省去维护中央的在线状态。 决定: 可以根据业务的特点权衡一下,如果主要的会话都发生在群聊,私聊极少且实时性要求低那可以采用网关机维护的方案,反之不采用。

    作者回复: 基本没错,不过这里有一点说一下:不管是不是网关机维护本地状态的方式,消息最终下发都是需要通过网关机推下去的哈,只是网关机本地维护状态的方式会浪费掉一些其他网关机的计算。

    2019-10-11
    11
  • zhxh
    如果通过订阅的方式,那么这条消息应该也需要把群成员列表带给网关吧,否则网关怎么筛选,可是万人群成员比较多,会导致这个消息包比较大,如果不带成员列表信息到网关,那么要求用户在和网关建立连接的时候,就要把自己加入的群列表信息带过来,绑定到网关,这样逻辑似乎和网关耦合比较严重,老师能详细解释一下么

    作者回复: 不需要建连时耦合群信息相关内容,这个问题可以采用分批下发给网关来解决,比如一批100这样。

    2019-10-11
    5
    7
  • 墙角儿的花
    老师 用websocket做长链接通信在网络较好情况下没什么问题 但在弱网下如2g 3g下就会频繁掉线,但是微信却做的这么好,地铁里仍然很稳定,它走的绝对不是websocket,它怎么做到的这么稳定通畅呢?有什么资料可以查看学习吗。

    作者回复: 之前有提到微信手机端应该走的是tcp私有协议,不是websocket。另外你提到的websocket弱网下容易掉线这个得具体case分析一下,不能把这个归结到websocket协议本身,底层一样都是基于tcp来传输的。连接不稳定和很多因素有关,连接入口的是否够快,有没有故障转移通道,能否快速识别到连接断开然后快速进行重连,网络传输的数据是否够小够精简,这些都有关系。微信有一些公开对外演讲的资料,可以查一下。

    2019-10-11
    3
    5
  • clip
    群聊的私有类型消息是不是要采用补齐而不是剔除的逻辑?因为加了一条仅自己可见的消息给其他人都创建不可见索引就得不偿失了。

    作者回复: 嗯,是的,私有消息是聚合,删除是剔除。

    2019-10-11
    3
    3
  • kamida
    老师 timer和flusher是所有群共用一个吗 那他们是怎么分别track不同的群的呢

    作者回复: timer和flusher是共用的,因为加未读是uid维度的,所以最终执行时按照uid来归并就可以了。

    2020-03-14
    2
  • 我行我素
    老师,想请问下:在用户删除消息的时候,把这条被删除消息加入到当前用户和群维度的一个删除索引中,这一步不是很明白

    作者回复: 其实就是把群聊消息删除这个单独记录一下,比如一个list里面,key是 uid_群id,value是这个uid在这个群删除的消息id。最后这个用户获取群消息时,从群维度的全量消息里剔除掉这个用户在这个群删除的这些消息id。

    2019-10-11
    3
    2
  • 🐾
    老师上午好、有些疑惑想跟您确认一下,消息多终端漫游,为解决用户离线期间收不到消息的问题,我们会在服务端按照接收用户维度,暂存用户离线期间的消息,等该用户下次上线时再进行拉取同步。 1、这里的同步,实际上是把服务端的消息同步到客户端,客户端也保存这些消息吧? 2、假如用户重新安装了APP,把客户端保存的数据也清空了,像这种情况下,一般处理是只同步离线消息,不同步历史数据吗? 3、如果客户端不保存消息记录,但又要显示所有历史数据,是不是不需要设计这个离线存储了,直接读取会话维度的所有消息就好?

    作者回复: 1. 是的。 2. 一般这种情况可以只下推离线消息,历史消息通过用户来触发拉取。 3. 不保存消息记录是指客户端不在本地存储所有消息?这种方式不太好呀,要不没网就看不了所有聊天记录了。

    2019-10-11
    2
  • 墙角儿的花
    群聊信息如果不采用收发箱的方式存储,碰见钉钉这种需要记录查看一条群消息哪些成员已阅,哪些未阅,就无能为力了

    作者回复: 这个是个问题,实际上也可以不需要按照uid维度来存储消息,按照消息维度存储已上报过 阅读事件的uid就可以。

    2019-10-11
    3
    2
  • yic
    老师,看了这么多节课程,突然有个问题想问:像微博、微信等这些APP一般的实时在线人数大概是什么量级?一台网关机大概能承载多少在线用户呀?

    作者回复: 像微博是千万级在线,微信具体数据不太清楚。单台网关机虽然理论上能到百万级别,但线上一般控制在几十万比较正常,如果是类似直播的业务会控制在更低水平。

    2019-11-21
    1
  • leslie
    其实点对点的在线下推:个人理解就是非常考验中间件存储/数据系统的设计,不合理的设计必然造成某块的负载过大,如何合理的设计和使用这些东西会成为关键。 老师的图中就有MQ和RMDB其实还有Nosql DB:刚好今天李玥老师的MQ刚刚完课,看完了老师的21课反向来学习这课的;看过国内的一些IM,其实这块真实的设计都被隐藏了;个人觉得这块如何修正成为自己的东西如何利用和设计好中间件存储应当是IM设计的一块重点和难点。 IM有听闻说简单的可是老师的课程学到现在:我发现如何合理的设计应用架构、数据系统、以及配合合适的监控应当是系统成败的关键。谢谢老师辛勤的分享以及困惑时的提点和教诲。

    作者回复: 哈哈,感谢支持和肯定~

    2019-10-15
    1
收起评论
显示
设置
留言
27
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部