默认

阿里IM技术分享(八):深度解密钉钉即时消息服务DTIM的技术设计

查看数: 88564 | 评论数: 25 | 收藏 6
关灯 | 提示:支持键盘翻页<-左 右->
    组图打开中,请稍候......
发布时间: 2022-08-15 00:30

正文摘要:

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

评论

寒武三叶虫1 发表于 8 个月前
引用:Frank 发表于 2023-03-14 08:21
这种设计明显是后期补的漏洞,完全推的思路,后期发现问题了,再补充。我们早期也是推,结果经常把客户端 ...

这里的rebase流程确实没有说清楚,只说客户端pts和服务端pts相差太大,就返回客户端rebase,然后客户端来拉最新的消息同时更新pts,由于pts是用户维度的,那么客户端来拉最新消息是怎么拉的?从文中描述看起来是像会话的最新消息,也就是说rebase的时候,需要用户把所有会话的最新消息都拉回去?如果是这样存在一个问题,用户的所有会话难道是同步入库的?如果是异步入库那么用户的会话列表就会有延迟,进而导致rebase流程也会有问题。

不清楚钉钉的rebase细节是啥
Frank 发表于 1 年前
引用:yqfclid 发表于 2022-08-31 16:58
DTIM 采用了会话维度划分:因为人和会话都是元数据,数据规模有限,消息数据近乎无限,消息归属于会话,会 ...

这里应该是,把消息推送到 用户所在单元同步服务;同步服务推送时,根据是否在线来确定.
Frank 发表于 1 年前
一说: 当消息进入Receiver之后,会先查询此cid:1001所在的单元,发现是Unit A,路由框架将请求转到A单元,消息在A单元持久化并通过A单元的同步协议,将数据推送到客户端
二说: Processor 消费到 IM 发送事件首先做按接收者的地域分布(DTIM 支持跨域部署, Geography,Geo)做消息事件分流
上面说的是会话路由,下面说的是消息同步分流? @JackJiang 请教站长
Frank 发表于 1 年前
引用:JackJiang 发表于 2022-08-23 10:34
嗯嗯,关键是要动手实践,光看看的话,很快就忘记了

确实要动手;反推他们的实现,然后画成完整的图逻辑,自圆其说也是可以的.
Frank 发表于 1 年前
引用:JackJiang 发表于 2022-08-18 21:59
这篇文章是目前为止,有关钉钉的最有价值技术干货,有兴趣的,一定读一读!

JackJiang 发表于 1 年前
引用:Frank 发表于 2023-03-14 08:23
拉消息肯定有个应用服务来聚合下。

这就叫专业
Frank 发表于 1 年前
引用:yqfclid 发表于 2022-08-31 16:58
DTIM 采用了会话维度划分:因为人和会话都是元数据,数据规模有限,消息数据近乎无限,消息归属于会话,会 ...

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

Frank 发表于 1 年前
引用:yqfclid 发表于 2022-08-31 16:58
DTIM 采用了会话维度划分:因为人和会话都是元数据,数据规模有限,消息数据近乎无限,消息归属于会话,会 ...

拉消息肯定有个应用服务来聚合下。
Frank 发表于 1 年前
引用:espen 发表于 2022-08-22 19:56
有个问题点,想请教下:

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

这种设计明显是后期补的漏洞,完全推的思路,后期发现问题了,再补充。我们早期也是推,结果经常把客户端推死,异常不太靠谱。
这里在线的时候:可以理解为每个用户有个队列 uid~msg1,msg 10,...,挨个的推下去;
离线变在线,也推,只是太多超过阀值2000条,则推条最新的让客户端来拉最新的,这里没有说清楚,其实应该拉 什么呢?那么多会话
Frank 发表于 1 年前
引用:mayongjian 发表于 2022-09-04 20:09
因为人和会话都是元数据,数据规模有限,消息数据近乎无限,消息归属于会话,会话与会话之间并无交集,消息 ...

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

其实就跟单元调用之间没什么关系了
Frank 发表于 1 年前
引用:JackJiang 发表于 2022-08-22 22:19
其实说到扩散写和扩散写,主要讨论的是群聊,群聊肯定会有一份全量消息存储。而针对每个端的记录,应该不 ...

但看文档的图说的数据模型例子:
确实同步这里不仅保存了位点,而且保存了消息; 但是 不一定全量,比如可以最多保存2000条的队列大小
Frank 发表于 1 年前
引用:天神佑护 发表于 2022-10-08 01:27
不懂就问,请教:4.2 中所指钉钉使用的异步消息队列和同步消息队列分别是什么产品呀?RocketMQ? Kafka? Pul ...

很显然是 rocketmq 自己的产品
rocketmq 有自己的特性,其他mq没有
Frank 发表于 1 年前
引用:yqfclid 发表于 2023-01-07 15:20
同步服务按接收者维度写入各自的同步队列,同时查取当前用户设备在线状态,当用户在线时捞取队列中未同步的 ...

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

这个是怎么查询当前设备的在线状态的,是查redis吗?如果是一条群聊消息  群里有一万个人  那岂不是要查1000次?
JackJiang 发表于 2 年前
引用:天神佑护 发表于 2022-10-08 01:27
不懂就问,请教:4.2 中所指钉钉使用的异步消息队列和同步消息队列分别是什么产品呀?RocketMQ? Kafka? Pul ...

它这个队列不一定指的是常规应用系统里用的MQ,也有可能是自已实现的一种队列算法或缓存读写机制,可以是一个模块或独立的服务
天神佑护 发表于 2 年前
不懂就问,请教:4.2 中所指钉钉使用的异步消息队列和同步消息队列分别是什么产品呀?RocketMQ? Kafka? Pulsar? 本文中涉及的消息队列都有哪些?
JackJiang 发表于 2 年前
引用:mayongjian 发表于 2022-09-04 20:09
因为人和会话都是元数据,数据规模有限,消息数据近乎无限,消息归属于会话,会话与会话之间并无交集,消息 ...

这一块在文章里其实是没有明确说清楚
mayongjian 发表于 2 年前
因为人和会话都是元数据,数据规模有限,消息数据近乎无限,消息归属于会话,会话与会话之间并无交集,消息处理时并没有跨单元的调用。因此,将不同的会话拆分到不同的单元,保障了消息数据仅在一个单元处理和持久化,不会产生跨单元的请求调用,进而实现了单元自封闭。

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

yqfclid 发表于 2 年前
DTIM 采用了会话维度划分:因为人和会话都是元数据,数据规模有限,消息数据近乎无限,消息归属于会话,会话与会话之间并无交集,消息处理时并没有跨单元的调用。因此,将不同的会话拆分到不同的单元,保障了消息数据仅在一个单元处理和持久化,不会产生跨单元的请求调用,进而实现了单元自封闭。


会话维度划分是指拉取消息的接口会固定在一个单元吗,是不是就是说在线消息的路由会跨单元进行路由,那么如何单元之间如何进行在线状态的同步呢
JackJiang 发表于 2 年前
引用:espen 发表于 2022-08-22 23:29
感谢站主热心解答,群消息存一份肯定是必须的,人维度存储索引确实要轻量很多,读起来效率也高,这样理解 ...

嗯嗯,关键是要动手实践,光看看的话,很快就忘记了

返回顶部