【融云分析】如何实现分布式场景下唯一 ID 生成

?背景?

对于分布式即时消息系统,要求每个消息的标识在集群中是全局唯一的,并根据生成时间按顺序排列。如何快速有效地生成消息数据的唯一标识是影响系统吞吐量的关键因素。那么,融云如何生成一个全球唯一的消息标识呢?

首先,您需要指定生成标识的核心要求:

1。全球唯一

2。订购

?设计?

融云消息数据的唯一标识长度为80位。每5位,32位编码执行一次,并转换成一个字符。字符的取值范围是(2 ~ 9)和(A ~ B)。其中,容易被肉眼混淆的数字0和1以及字母0和1已经被移除。这样,80位可以转换成16个字符,加上3个分隔符(-),16个字符被分成4组,最后得到19个字符的唯一标识。这种设计可以确保生成的标识有序且易于阅读。

如上图所示,80位分为4段:

1。第一段,42位,用于存储时间戳,时间戳可以表达为2109,足够开发人员目前使用。时间戳数据按高顺序排列,可以确保生成的唯一标识按时间顺序排列。这是消息标识必须满足的条件。

2。第二个12位段用于存储自旋转标识。我们知道时间戳的精度是毫秒。对于一个1亿级即时消息系统来说,在同一毫秒内生成多个消息太正常了。这个旋转标识是自动增加在同一毫秒内下降的消息数。12位意味着在同一毫秒内,单个主机可以识别多达4096条(2到12次方)消息。

3。第三个4位段用于标识会话类型。4位,最多可识别16个会话,足以涵盖常见会话类型,如单次聊天、群聊、系统消息、聊天室、客户服务和公共号码。

4。第四段22位,会话号。例如群聊中的群组标识、聊天室中的聊天室标识等。结合第三种会话类型,可以唯一地标识会话。其他身份生成算法保留两个段来分别标识数据中心号和主机号(如雪花算法)。相反,我们使用这两个部分来标识会话。这样,身份生成就可以直接集成到业务服务中,而不需要考虑服务所在的主机,从而实现无状态的扩展和收缩。

?实施过程?

消息标识总共占80位,在计算过程中我们分为两部分,64位高(记录为高位)和16位低(记录为低位)。

1。获取当前系统的时间戳,并将其分配给消息标识的64位高位;

2。获取旋转标识,将高位向左移动12位,并将旋转标识拼接到低位12位;

其中,自旋标识是一个从0到4095的数字,按顺序递增。生成规则如下:

3。前一步中的高位向左移动4位,会话类型拼接到低位4位;

4。获取会话标识哈希值的较低22位,并将其记录为会话;

5。高位向左移动6位,并将sessionIdInt的高6位拼接到高位的低6位;

6。将会话标识的低16位作为LoBits

7。高位与低位拼接得到80位消息标识。唯一的消息标识可以通过32位编码获得。编码规则如下:从左到右,每5位转换成一个整数,相应的字符可以在下表中找到,该整数作为下标。

摘要:

这种标识生成方法需要注意确保自旋标识的生成是线程安全的。避免在并发情况下生成相同的标识。此外,这种身份生成算法严重依赖于系统时间。如果系统时间减少,可以重复生成标识。