默认
打赏 发表评论 25
想开发IM:买成品怕坑?租第3方怕贵?找开源自已撸?尽量别走弯路了... 找站长给点建议
阿里IM技术分享(八):深度解密钉钉即时消息服务DTIM的技术设计
微信扫一扫关注!

本文引用自InfoQ社区“5亿用户如何高效沟通?钉钉首次对外揭秘即时消息服务DTIM”一文,作者陈万红等、策划褚杏娟,即时通讯网有修订和改动,原文链接在文末。


一、引言


本文是国内企业IM的事实王者钉钉首次对外深度解密其即时消息服务(即DingTalk IM,简称DTIM)的技术设计实践。

本篇文章内容将从模型设计原理到具体的技术架构、最底层的存储模型到跨地域的单元化等,全方位展现了 DTIM 在实际生产应用中所遇到的各种技术挑战及相应的解决方案,希望借本文内容的分享能为国内企业级IM的开发带来思考和启发。

cover-opti.jpg

二、系列文章


本文是系列文章的第8篇,总目录如下:


相关文章:

三、钉钉的技术挑战


0.jpg

钉钉已经有 2100 万 + 组织、5 亿 + 注册用户在使用。DTIM 为钉钉用户提供即时消息服务,用于组织内外的沟通,这些组织包括公司、政府、学校等,规模从几人到百万人不等。

DTIM 有着丰富的功能,单聊、各种类型的群聊、消息已读、文字表情、多端同步、动态卡片、专属安全和存储等等。

同时:钉钉内部很多业务模块,比如文档、钉闪会、Teambition、音视频、考勤、审批等,每个业务都在使用 DTIM,用于实现业务流程通知、运营消息推送、业务信令下发等。每个业务模块对于 DTIM 调用的流量峰值模型各有差别,对可用性要求也不尽相同。DTIM 需要能够面对这些复杂的场景,保持良好的可用性和体验,同时兼顾性能与成本

通用的即时消息系统对消息发送的成功率、时延、到达率有很高的要求,企业 IM 由于 ToB 的特性,在数据安全可靠、系统可用性、多终端体验、开放定制等多个方面有着极致的要求。

构建稳定高效的企业 IM 服务,DTIM 主要面临的挑战是:

  • 1)企业 IM 极致的体验要求对于系统架构设计的挑战:比如数据长期保存可漫游、多端数据同步、动态消息等带来的数据存储效率和成本压力,多端数据同步带来的一致性问题等;
  • 2)极限场景冲击、依赖系统错误带来的可用性问题:比如超大群消息,突发疫情带来的线上办公和线上教学高并发流量,系统需要能够应对流量的冲击,保障高可用;同时在中间件普遍可用性不到 99.99% 的时候,DTIM 服务需要保障核心功能的 99.995% 的可用性;
  • 3)不断扩大的业务规模,对于系统部署架构的挑战:比如持续增长的用户规模,突发事件如席卷全球的疫情,单地域架构已经无法满足业务发展的要求。

DTIM 在系统设计上:

  • 1)为了实现消息收发体验、性能和成本的平衡,设计了高效的读写扩散模型和同步服务,以及定制化的 NoSQL 存储;
  • 2)通过对 DTIM 服务流量的分析,对于大群消息、单账号大量的消息热点以及消息更新热点的场景进行了合并、削峰填谷等处理;
  • 3)核心链路的应用中间件的依赖做容灾处理,实现了单一中间件失败不影响核心消息收发,保障基础的用户体验。

在消息存储过程中,一旦出现存储系统写入异常,系统会回旋缓冲重做,并且在服务恢复时,数据能主动向端上同步。

随着用户数不断增长,单一地域已无法承载 DTIM 的容量和容灾需求,DTIM 实现了异地多单元的云原生的弹性架构

在分层上遵从的原则为重云轻端:业务数据计算、存储、同步等复杂操作尽量后移到云端处理,客户端只做终态数据的接收、展示,通过降低客户端业务实现的复杂度,最大化地提升客户端迭代速度,让端上开发可以专注于提升用户的交互体验,所有的功能需求和系统架构都围绕着该原则做设计和扩展。

以下章节我们将对 DTIM 做更加详细的介绍。

四、模型设计


4.1、DTIM系统架构


低延迟、高触达、高可用一直是 DTIM 设计的第一原则,依据这个原则在架构上 DTIM 将系统拆分为三个服务做能力的承载。

三个服务分别是:

  • 1)消息服务:负责 IM 核心消息模型和开放 API,IM 基础能力包括消息发送、单聊关系维护、群组元信息管理、历史消息拉取、已读状态通知、IM 数据存储以及跨地域的流量转发;
  • 2)同步服务:负责用户消息数据以及状态数据的端到端同步,通过客户端到服务端长连接通道做实时的数据交互,当钉钉各类设备在线时 IM 及上游各业务通过同步服务做多端的数据同步,保障各端数据和体验一致;
  • 3)通知服务:负责用户第三方通道维护以及通知功能,当钉钉的自建通道无法将数据同步到端上时,通过三方提供的通知和透传能力做消息推送,保障钉钉消息的及时性和有效性。

同步服务和通知服务除了服务于消息服务,也面向其他钉钉业务比如音视频、直播、Ding、文档等多端 (多设备) 数据同步。

图1:DTIM架构图 ▼
1.png

上图展示了 DTIM 系统架构,接下来详细介绍消息收发链路。

4.2、消息收发链路


图2:DTIM消息处理架构 ▼
2.png

1)消息发送:消息发送接口由 Receiver 提供,钉钉统一接入层将用户从客户端发送的消息请求转发到 Receiver 模块,Receiver 校验消息的合法性(文字图片等安全审核、群禁言功能是否开启或者是否触发会话消息限流规则等)以及成员关系的有效性(单聊校验二者聊天、群聊校验发送者在群聊成员列表中),校验通过后为该消息生成一个全局唯一的 MessageId 随消息体以及接收者列表打包成消息数据包投递给异步队列,由下游 Processor 处理。消息投递成功之后,Receiver 返回消息发送成功的回执给客户端。

2)消息处理 :Processor 消费到 IM 发送事件首先做按接收者的地域分布(DTIM 支持跨域部署, Geography,Geo)做消息事件分流,将本域用户的消息做本地存储入库(消息体、接收者维度、已读状态、个人会话列表红点更新),最后将消息体以及本域接收者列表打包为 IM 同步事件通过异步队列转发给同步服务。

3)消息接收 :同步服务按接收者维度写入各自的同步队列,同时查取当前用户设备在线状态,当用户在线时捞取队列中未同步的消息,通过接入层长连接推送到各端。当用户离线时,打包消息数据以及离线用户状态列表为 IM 通知事件,转发给通知服务的 PNS 模块,PNS 查询离线设备做三方厂商通道推送,至此一条消息的推送流程结束。

4.3、存储模型设计


了解 IM 服务最快的途径就是掌握它的存储模型。

业界主流 IM 服务对于消息、会话、会话与消息的组织关系虽然不尽相同,但是归纳起来主要是两种形式:写扩散读聚合、读扩散写聚合。

所谓读写扩散其实是定义消息在群组会话中的存储形式。如下图所示。

图3:读模式和写模式 ▼
3.png

如上图所示:

  • 1)读扩散的场景:消息归属于会话,对应到存储中相当于有张 conversation_message 的表存储着该会话产生的所有消息 (cid->msgid->message,cid 会话 ID、msgid 消息 ID、message 消息),这样实现的好处是消息入库效率高,只存储会话与消息的绑定关系即可;
  • 2)写扩散的场景:会话产生的消息投递到类似于个人邮件的收件箱,即 message_inbox 表,存储个人的所有消息(uid->msgid->message, uid 用户 ID、msgid 消息 ID、message 消息),基于这种实现,会话中的每条消息面向不同的接收者可以呈现出不同状态。

DTIM 对 IM 消息的及时性、前后端存储状态一致性要求异常严格,特别对于历史消息漫游的诉求十分强烈,当前业界 IM 产品对于消息长时间存储和客户端历史消息多端漫游都做得不尽如人意,主要是存储成本过高。因此在产品体验与投入成本之间需要找到一个平衡点。

采用读扩散:在个性化的消息扩展及实现层面有很大的约束。

采用写扩散带来的问题也很明显:一个群成员为 N 的会话一旦产生消息就会扩散 N 条消息记录,如果在消息发送和扩散量较少的场景,这样的实现相比于读扩散落地更为简单,存储成本也不是问题。但是 DTIM 会话活跃度超高,一条消息的平均扩散比可以达到 1:30,超大群又是企业 IM 最核心的沟通场景,如果采用完全写扩散所带来存储成本问题势必制约钉钉业务发展。

所以,在 DTIM 的存储实现上,钉钉采取了混合的方案,将读扩散和写扩散针对不同场景做了适配,最终在用户视角系统会做统一合并,如下图所示。

图4:DTIM 读写混合模式 ▼
4.png

作为读扩散、写扩散方案的混合形式存在,用户维度的消息分别从 conversation_messagemessage_inbox 表中获取,在应用侧按消息发送时间做排序合并,conversation_message 表中记录了该会话面向所有群成员接收的普通消息 N(Normal),而 message_inbox 表在以下两种场景下被写入:

1)第一种是:定向消息 P(Private,私有消息),群会话中发送的消息指定了接收者范围,那么会直接写入到接收者的 message_inbox 表中,比如红包的领取状态消息只能被红包发送者可见,那么这种消息即被定义为定向消息。

2)第二种是:归属于会话消息的状态转换 NP(Normal to Private,普通消息转私有消息),当会话消息通过某种行为使得某些消息接收者的消息状态发生转换时,该状态会写入到 message_inbox 表中,比如用户在接收侧删除了消息,那么消息的删除状态会写入到 message_inbox 中,在用户拉取时会通过 message_inbox 的删除状态将 conversation_message 中的消息做覆盖,最终用户拉取不到自己已删除的消息。

当用户在客户端发起某个会话的历史消息漫游请求时,服务端根据用户上传的消息截止时间(message_create_time)分别从 conversation_message 表和 message_inbox 表拉取消息列表,在应用层做状态的合并,最终返回给用户合并之后的数据,N、P、NP 三种类型消息在消息个性化处理和存储成本之间取得了很好的平衡。

4.4、同步模型设计


4.4.1推送模型


用户在会话中发出的消息和消息状态变更等事件是如何同步到端上呢?

业界关于消息的同步模型的实现方案大致有三种:

  • 1)客户端拉取方案;
  • 2)服务端推送方案;
  • 3)服务端推送位点之后客户端拉取的推拉结合方案。

三种方案各有优劣,在此简短总结:

  • 1)首先:客户端拉取方案的优点是该方案实施简单、研发成本低,是传统的 B/S 架构。劣势是效率低下,拉取间隔控制权在客户端,对于 IM 这种实时的场景,很难设置一个有效的拉取间隔,间隔太短对服务端压力大,间隔太长时效性差;
  • 2)其次:服务端主动推送方案的优点是低延迟、能做到实时,最重要的主动权在服务端。劣势相对拉取方案,如何协调服务端和客户端的处理能力存在问题;
  • 3)最后:推拉结合这个方案整合了拉和推的优点,但是方案更复杂,同时会比推的方案多一次 RTT,特别是在移动网络的场景下,不得不面临功耗和推送成功率的问题。

DTIM 相对传统 toC 的场景,有较明显的区别:

1)第一是对实时性的要求:在企业服务中,比如员工聊天消息、各种系统报警,又比如音视频中的共享画板,无不要求实时事件同步,因此需要一种低延时的同步方案。

2)第二是弱网接入的能力:在 DTIM 服务的对象中,上千万的企业组织涉及各行各业,从大城市 5G 的高速到偏远的山区弱网,都需要 DTIM 的消息能发送、能触达。对于复杂的网络环境,需要服务端能判断接入环境,并依据不同的环境条件调整同步数据的策略。

3)第三是功耗可控成本可控:在 DTIM 的企业场景中,消息收发频率比传统的 IM 多出一个数量级,在这么大的消息收发场景怎么保障 DTIM 的功耗可控,特别是移动端的功耗可控,是 DTIM 必须面对的问题。在这种要求下,就需要 DTIM 尽量降低 IO 次数,并基于不同的消息优先级进行合并同步,既能要保障实时性不被破坏,又要做到低功耗。

从以上三点可知,服务端主动推送的模型更适合 DTIM 场景:

  • 1)首先可以做到极低的延时,保障推送耗时在毫秒级别;
  • 2)其次是服务端能通过用户接入信息判断用户接入环境好坏,进行对应的分包优化,保障弱网链路下的成功率;
  • 3)最后是主动推送相对于推拉结合来说,可以降低一次 IO,对 DTIM 这种每分钟过亿消息服务来说,能极大的降低设备功耗,同时配合消息优先级合并包的优化,进一步降低端的功耗。

虽说主动推送有诸多优势,但是客户端会离线,甚至客户端处理速度无法跟上服务端的速度,必然导致消息堆积。

DTIM 为了协调服务端和客户端处理能力不一致的问题,支持 Rebase 的能力,当服务端消息堆积的条数达到一定阈值时触发 Rebase,客户端会从 DTIM 拉取最新的消息,同时服务端跳过这部分消息从最新的位点开始推送消息。DTIM 称这个同步模型为推优先模型(Preferentially-Push Model,PPM)。

在基于 PPM 的推送方案下,为了保障消息的可靠达到,DTIM 还做一系列优化。

这些优化具体是:

  • 1)支持消息可重入:服务端可能会针对某条消息做重复推送,客户端需要根据 msgId 做去重处理,避免端上消息重复展示。
  • 2)支持消息排序:服务端推送消息特别是群比较活跃的场景,某条消息由于推送链路或者端侧网络抖动,推送失败,而新的消息正常推送到端侧,如果端上不做消息排序的话,消息列表就会发生乱序,所以服务端会为每条消息分配一个时间戳,客户端每次进入消息列表就是根据时间戳做排序再投递给 UI 层做消息展示。
  • 3)支持缺失数据回补:在某个极端情况下客户端群消息事件比群创建事件更早到达端上,此时端上没有群的基本信息消息也就无法展现,所以需要客户端主动向服务端拉取群信息同步到本地,再做消息的透出。

4.4.2多端数据一致性


多端数据一致性问题一直是多端同步最核心的问题,单个用户可以同时在 PC、Pad 以及 Mobile 登录,消息、会话红点等状态需要在多端保持一致,并且用户更换设备情况下消息可以做全量的回溯。

基于上面的业务诉求以及系统层面面临的诸多挑战,钉钉自研了同步服务来解决一致性问题。

钉钉的同步服务的设计理念和原则如下:

  • 1)统一消息模型抽象,对于 DTIM 服务产生的新消息以及已读事件、会话增删改、多端红点清除等事件统一抽象为同步服务的事件;
  • 2)同步服务不感知事件的类型以及数据序列化方式。同步服务为每个用户的事件分配一个自增的 ID(注:这里非连续递增),确保消息可以根据 ID 做遍历的有序查询;
  • 3)统一同步队列,同步服务为每个用户分配了一个 FIFO 的队列存储,自增 id 和事件串行写入队列;当有事件推送时,服务端根据用户当前各端在线设备状态做增量变更,将增量事件推送到各端;
  • 4)根据设备和网络质量的不同可以做多种分包推送策略,确保消息可以有序、可靠、高效的发送给客户端。

上面介绍了 DTIM 的存储模型以及同步模型的设计与思考:

  • 1)在存储优化中,存储会基于 DTIM 消息特点进行深度优化,并会对其中原理以及实现细节做深入分析与介绍;
  • 2)在同步机制中,会进一步介绍多端同步机制是如何保障消息必达以及各端消息一致性。

五、消息存储设计


DTIM 底层使用了表格存储作为消息系统的核心存储系统,表格存储是一个典型 LSM 存储架构,读写放大是此类系统的典型问题。

LSM 系统通过 Major Compaction 来降低数据的 Level 高度,降低读取数据放大的影响。在 DTIM 的场景中,实时消息写入超过百万 TPS,系统需要划归非常多的计算资源用于 Compaction 处理,但是在线消息读取延迟毛刺依旧严重。

在存储的性能分析中,我们发现如下几个特点:

  • 1)6% 的用户贡献了 50% 左右的消息量,20% 的用户贡献了 74% 的消息量。高频用户产生的消息远多于低频用户,在 Flush MemTable 时,高频用户消息占据了文件的绝大部分;
  • 2)对于高频的用户,由于其“高频”的原因,当消息进入 DTIM,系统发现用户设备在线(高概率在线),会立即推送消息,因此需要推送的消息大部分在内存的 MemTable 中;
  • 3)高频用户产生大量的消息,Compaction 耗费了系统大量的计算和 IO 资源;
  • 4)低频的用户消息通常散落在多个文件当中。

从上面的四个表现来看,我们能得出如下结论:

  • 1)绝大部分 Compaction 是无效的计算和 IO,由于大量消息写入产生大量的文件,但是高频的用户消息其实已经下推给用户的设备,Compaction 对读加速效果大打折扣。反而会抢占计算资源,同时引起 IO 抖动;
  • 2)低频用户由于入库消息频率低,在 Flush 之后的文件中占比低;同时用户上线频率低,期间会累计较多的待接收的消息,那么当用户上线时,连续的历史消息高概率散落在多个文件当中,导致遍历读取消息毛刺,严重的有可能读取超时。

为了解决此类问题,我们采用分而治之方法,将高频用户和低频用户的消息区别对待。

我们借鉴了 WiscKey KV 分离技术的思想,就是将到达一定阈值的 Value 分离出来,降低这类消息在文件中的占比进而有效的降低写放大的问题。

附:WiscKey KV原始论文附件下载:
WiscKey:Separating Keys from Values in SSD-conscious Storage(52im.net).pdf (2.24 MB , 下载次数: 14 , 售价: 1 金币)

即时通讯网 - 即时通讯开发者社区! 来源: - 即时通讯开发者社区!

上一篇:基于Netty,从零开发IM(四):编码实践篇(系统优化)下一篇:即时通讯安全篇(十一):IM聊天系统安全手段之通信连接层加密技术

本帖已收录至以下技术专辑

推荐方案
评论 25
这篇文章是目前为止,有关钉钉的最有价值技术干货,有兴趣的,一定读一读!
有个问题点,想请教下:

在4.3中,提到钉钉的消息存储使用的是消息读扩散+写扩散的方式,群内普通消息写到conversation_message这张表,P和NP消息写到message_inbox表。而且还展示了拉消息的逻辑,第七章7.2.2也作证了这一点。

但是在第六章中,讲数据的多终端同步和离线同步,有点类似于漫游的功能,拉的消息会持久化一份到Event Store表,然后PTS记录每个端拉取的消息seq,这里怎么看怎么像消息的写扩散。同样也展示了对应拉消息的逻辑


那么问题来了: 只看普通消息,前面说用读扩散,后面同步的时候又是按人维度以写扩散的方式单独存储一份,这个岂不是有矛盾?难道同步服务和在线消息推送是解耦的?多端在线直接推,并抄一份到同步服务,同步服务做持久化,同一用户离线的终端上线后再到同步服务个人消息存储的队列来拉取,这样在消息推送可以保证实时,拉消息逻辑又可以变得简单,解释起来貌似要合理一点,但是文章中没有体现出来。

麻烦大佬们帮忙看看这个,怎么看待这个问题

有个问题点,想请教下。

在4.3中,提到钉钉的消息存储使用的是消息读扩散+写扩散的方式,群内普通消息写到conversation_message这张表,P和NP消息写到message_inbox表。而且还展示了拉消息的逻辑。7.2.2也作证了这一点

但是在第六章中,讲数据的多终端同步和离线同步,有点类似于漫游的功能,拉的消息会持久化一份到Event Store表,然后PTS记录每个端拉取的消息seq,这里怎么看怎么像消息的写扩散。同样也展示了对应拉消息的逻辑

那么问题来了: 只看普通消息,前面说用读扩散,后面同步的时候又是按人维度以写扩散的方式单独存储一份,这个岂不是有矛盾?难道同步服务和在线消息推送是解耦的?多端在线直接推,并抄一份到同步服务,同步服务做持久化,同一用户离线的终端上线后再到同步服务个人消息存储的队列来拉取,这样在消息推送可以保证实时,拉消息逻辑又可以变得简单,解释起来貌似要合理一点,但是文章中没有体现出来。

看看各位大佬对这个点怎么看
引用:espen 发表于 2022-08-22 20:01
有个问题点,想请教下。

在4.3中,提到钉钉的消息存储使用的是消息读扩散+写扩散的方式,群内普通消息写 ...

其实说到扩散写和扩散写,主要讨论的是群聊,群聊肯定会有一份全量消息存储。而针对每个端的记录,应该不会是每个端都有个inbox收件箱存全量消息,肯定存的是相关的标识,从而方便增量同步更新。文章里因为涉及的技术点比较广,所以单个技术点来说,可能说的比较模糊,参考一下就好了。大厂的东西没必要完全去照搬
引用:JackJiang 发表于 2022-08-22 22:19
其实说到扩散写和扩散写,主要讨论的是群聊,群聊肯定会有一份全量消息存储。而针对每个端的记录,应该不 ...

感谢站主热心解答,群消息存一份肯定是必须的,人维度存储索引确实要轻量很多,读起来效率也高,这样理解也合理很多。当时看的时候觉得他这样说有点奇怪,每个人再写一份挺浪费钱。。。但是想想,这样这样客户端做逻辑会方便很多,客户端也会流畅很多,毕竟阿里,有钱(手动狗头)。

学习一下大厂的架构,回头自己实现的时候有个参考的模型,哈哈哈。

再次感谢站主。
引用:espen 发表于 2022-08-22 23:29
感谢站主热心解答,群消息存一份肯定是必须的,人维度存储索引确实要轻量很多,读起来效率也高,这样理解 ...

嗯嗯,关键是要动手实践,光看看的话,很快就忘记了
DTIM 采用了会话维度划分:因为人和会话都是元数据,数据规模有限,消息数据近乎无限,消息归属于会话,会话与会话之间并无交集,消息处理时并没有跨单元的调用。因此,将不同的会话拆分到不同的单元,保障了消息数据仅在一个单元处理和持久化,不会产生跨单元的请求调用,进而实现了单元自封闭。


会话维度划分是指拉取消息的接口会固定在一个单元吗,是不是就是说在线消息的路由会跨单元进行路由,那么如何单元之间如何进行在线状态的同步呢
因为人和会话都是元数据,数据规模有限,消息数据近乎无限,消息归属于会话,会话与会话之间并无交集,消息处理时并没有跨单元的调用。因此,将不同的会话拆分到不同的单元,保障了消息数据仅在一个单元处理和持久化,不会产生跨单元的请求调用,进而实现了单元自封闭。

”不会产生跨单元的请求调用“ 如果 A与B通信,并且A与B处于不同单元,不会跨单元请求调用,这个怎么理解啊

引用:mayongjian 发表于 2022-09-04 20:09
因为人和会话都是元数据,数据规模有限,消息数据近乎无限,消息归属于会话,会话与会话之间并无交集,消息 ...

这一块在文章里其实是没有明确说清楚
不懂就问,请教:4.2 中所指钉钉使用的异步消息队列和同步消息队列分别是什么产品呀?RocketMQ? Kafka? Pulsar? 本文中涉及的消息队列都有哪些?
引用:天神佑护 发表于 2022-10-08 01:27
不懂就问,请教:4.2 中所指钉钉使用的异步消息队列和同步消息队列分别是什么产品呀?RocketMQ? Kafka? Pul ...

它这个队列不一定指的是常规应用系统里用的MQ,也有可能是自已实现的一种队列算法或缓存读写机制,可以是一个模块或独立的服务
同步服务按接收者维度写入各自的同步队列,同时查取当前用户设备在线状态,当用户在线时捞取队列中未同步的消息,通过接入层长连接推送到各端。当用户离线时,打包消息数据以及离线用户状态列表为 IM 通知事件,转发给通知服务的 PNS 模块,PNS 查询离线设备做三方厂商通道推送,至此一条消息的推送流程结束。

这个是怎么查询当前设备的在线状态的,是查redis吗?如果是一条群聊消息  群里有一万个人  那岂不是要查1000次?
引用:yqfclid 发表于 2023-01-07 15:20
同步服务按接收者维度写入各自的同步队列,同时查取当前用户设备在线状态,当用户在线时捞取队列中未同步的 ...

多级缓存:本地缓存
签名: im从业10年以上,欢迎切磋![url=http://www.52im.net/static/image/smiley/default/handshake.gif]http://www.52im.net/static/image/smiley/default/handshake
引用:天神佑护 发表于 2022-10-08 01:27
不懂就问,请教:4.2 中所指钉钉使用的异步消息队列和同步消息队列分别是什么产品呀?RocketMQ? Kafka? Pul ...

很显然是 rocketmq 自己的产品
rocketmq 有自己的特性,其他mq没有
签名: im从业10年以上,欢迎切磋![url=http://www.52im.net/static/image/smiley/default/handshake.gif]http://www.52im.net/static/image/smiley/default/handshake
引用:JackJiang 发表于 2022-08-22 22:19
其实说到扩散写和扩散写,主要讨论的是群聊,群聊肯定会有一份全量消息存储。而针对每个端的记录,应该不 ...

但看文档的图说的数据模型例子:
确实同步这里不仅保存了位点,而且保存了消息; 但是 不一定全量,比如可以最多保存2000条的队列大小
签名: im从业10年以上,欢迎切磋![url=http://www.52im.net/static/image/smiley/default/handshake.gif]http://www.52im.net/static/image/smiley/default/handshake
引用:mayongjian 发表于 2022-09-04 20:09
因为人和会话都是元数据,数据规模有限,消息数据近乎无限,消息归属于会话,会话与会话之间并无交集,消息 ...

业务单元服务-直接跟各个接入层按需对接:
客户端A -->接入层--> 根据会话直接对接: 单元A 单元B,单元C ,根据业务路由获取,不用跨单元调用

其实就跟单元调用之间没什么关系了
签名: im从业10年以上,欢迎切磋![url=http://www.52im.net/static/image/smiley/default/handshake.gif]http://www.52im.net/static/image/smiley/default/handshake
引用:espen 发表于 2022-08-22 19:56
有个问题点,想请教下:

在4.3中,提到钉钉的消息存储使用的是消息读扩散+写扩散的方式,群内普通消息写 ...

这种设计明显是后期补的漏洞,完全推的思路,后期发现问题了,再补充。我们早期也是推,结果经常把客户端推死,异常不太靠谱。
这里在线的时候:可以理解为每个用户有个队列 uid~msg1,msg 10,...,挨个的推下去;
离线变在线,也推,只是太多超过阀值2000条,则推条最新的让客户端来拉最新的,这里没有说清楚,其实应该拉 什么呢?那么多会话
签名: im从业10年以上,欢迎切磋![url=http://www.52im.net/static/image/smiley/default/handshake.gif]http://www.52im.net/static/image/smiley/default/handshake
引用:yqfclid 发表于 2022-08-31 16:58
DTIM 采用了会话维度划分:因为人和会话都是元数据,数据规模有限,消息数据近乎无限,消息归属于会话,会 ...

拉消息肯定有个应用服务来聚合下。
签名: im从业10年以上,欢迎切磋![url=http://www.52im.net/static/image/smiley/default/handshake.gif]http://www.52im.net/static/image/smiley/default/handshake
引用:yqfclid 发表于 2022-08-31 16:58
DTIM 采用了会话维度划分:因为人和会话都是元数据,数据规模有限,消息数据近乎无限,消息归属于会话,会 ...

消息肯定跨单元路由的;
在线状态,同步到不同的中心。推送给用户时,查询状态是否在线。

签名: im从业10年以上,欢迎切磋![url=http://www.52im.net/static/image/smiley/default/handshake.gif]http://www.52im.net/static/image/smiley/default/handshake
打赏楼主 ×
使用微信打赏! 使用支付宝打赏!

返回顶部