◀背景▶

对于一套分布式部署的 IM 系统,要求每条消息的 ID 要保证在集群中全局唯一且按生成时间有序排列。如何快速高效的生成消息数据的唯一 ID ,是影响系统吞吐量的关键因素。那么,融云是如何做到生成全局唯一消息 ID 的呢?

首先需要明确下 ID 生成的核心需求:

1. 全局唯一

2. 有序

◀设计▶

融云消息数据的唯一 ID 长度采用 80 Bit 。每 5 个 Bit ,进行一次 32 进制编码,转换为一个字符,字符取值范围是,( 2 ~ 9 ) 和 ( A ~ B ),其中,已经去掉容易造成肉眼混淆的,数字 0 和 1 ,及字母 O 和 I 。这样,80 Bit 可以转换为 16 个字符,再加上 3 个分隔符( - ),将 16 个字符分为 4 组,最终得到一个 19 字符的唯一 ID 。 这样设计,即可以保证生成的 ID 是有序的,也能方便阅读。

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

1. 第一段 42 Bit ,用于存放时间戳,最长可表示到 2109 年,足够开发者当前使用了。时间戳数据放在高位,可以保证生成的唯一 ID 是按时间有序的,这个是消息 ID 必须要满足的条件。

2. 第二段 12 Bit ,用于存放自旋转 ID 。我们知道,时间戳的精度是到毫秒的,对于一套亿级 IM 系统来说,同一毫秒内产生多条消息太正常不过了,这个自旋 ID 就是在给落到同一毫秒内的消息进行自增编号。12 Bit 则意味着,同一毫秒内,单台主机中最多可以标识 4096( 2 的 12 次方)条消息。

3. 第三段 4 Bit ,用于标识会话类型。4 Bit ,最多可以标识 16 中会话,足够涵盖单聊、群聊、系统消息、聊天室、客服及公众号等常用会话类型。

4. 第四段 22 Bit ,会话 ID 。如群聊中的群 ID ,聊天室中的聊天室 ID 等。与第三段会话类型组合在一起,可以唯一标识一个会话。其他的一些 ID 生成算法,会预留两段,分别用来标识数据中心编号和主机编号(如 SnowFlake 算法),我们并没有这样做,而是将这两段用来标识会话。这样,ID 生成可以直接融入到业务服务中,且不必关心服务所在的主机,做到无状态扩缩容。

◀实现过程▶

消息 ID 共占 80 Bit ,计算时我们分为两部分,高 64 Bit (记为 highBits )和低 16 Bit (记为 lowBits )。

1. 获取当前系统的时间戳,并赋值给消息 ID 的高 64 Bit ;

2. 获取一个自旋 ID , highBits 左移 12 位,并将自旋 ID 拼接到低 12 位中;

其中,自旋 ID 是一个从 0 到 4095 范围内,顺序递增的数,生成规则如下:

3. 上步的 highBits 左移 4 位,将会话类型拼接到低 4 位;

4. 取会话 ID 哈希值的低 22 位,记为 sessionIdInt ;

5. highBits 左移 6 位,并将 sessionIdInt 的高 6 位拼接到 highBits 的低 6 位中;

6. 取会话 ID 的低 16 位作为 lowBits ;

7. highBits 与 lowBits 拼接,得到 80 Bit 的消息 ID 。对其进行 32 进制编码,即可得到唯一消息 ID 。编码规则如下:从左至右,每 5 个 Bit 转换为一个整数,以这个整数作为下标,即可在下表中找到对应的字符。

总结:

这种 ID 生成的方式,需要注意保证自旋 ID 的生成是线程安全的。避免在并发情况下,生成出同样的 ID 。另外,此 ID 生成算法,强烈依赖系统时间,如果系统时间被改小,也可能造成 ID 生成重复。

转载于:https://blog.51cto.com/14084807/2370002

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

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

    ◀背景▶ 对于一套分布式部署的 IM 系统,要求每条消息的 ID 要保证在集群中全局唯一且按生成时间有序排列.如何快速高效的生成消息数据的唯一 ID ,是影响系统吞吐量的关键因素.那么,融云是如何做到 ...

  2. 难道主键除了自增就是GUID?支持k8s等分布式场景下的id生成器了解下

    背景 主键(Primary Key),用于唯一标识表中的每一条数据.所以,一个合格的主键的最基本要求应该是唯一性. 那怎么保证唯一呢?相信绝大部分开发者在刚入行的时候选择的都是数据库的自增id,因为这 ...

  3. 如何在分布式场景下生成全局唯一 ID ?

    作者 l 会点代码的大叔(CodeDaShu) 在分布式系统中,有一些场景需要使用全局唯一 ID ,可以和业务场景有关,比如支付流水号,也可以和业务场景无关,比如分库分表后需要有一个全局唯一 ID,或 ...

  4. 干货 | 解决分布式场景下数据一致性问题,我有办法!

    此次分享的缘由 支付重构 考虑支付重构的时候,自然想到原本属于一个本地事务中的处理,现在要跨应用了要怎么处理.拿充值订单举个栗子吧,假设:原本订单模块和账户模块是放在一起的,现在需要做服务拆分,拆分成 ...

  5. 全域调度:云边协同在视频场景下的探索实践

    随着多媒体业务越来越多的涌现,每个业务都有不同的差异性特征.各大视频云厂商遇到的最大挑战是如何打造多媒体分发网络,使用最低成本为多业务提供最优质网络体验.本次分享邀请到了华为云算法专家--杨昌鹏老师, ...

  6. sqlserver检测到基于一致性的逻辑_面试官;解决分布式场景下数据一致性问题

    在这一篇中主要回答目前分布式事务问题是怎么解决的?行业中有什么解决方案?这些解决方案分别有什么优缺点?别人是怎么做的?我们可以怎么来做? 支付重构 考虑支付重构的时候,自然想到原本属于一个本地事务中的 ...

  7. vb6 串口同时读取写入数据怎么避免冲突_分布式场景下的数据复制究竟怎么做...

    主从复制 集群中有一个主节点,写操作都必须经过主节点完成,读操作主从节点都可以处理. 同步复制 数据在副本上落盘才返回. 优点:保证在副本上的数据是最新数据. 缺点:延迟高,响应慢. 异步复制 数据不 ...

  8. 分布式场景下数据一致性的问题——【分布式锁】 Java常用技术方案

    2019独角兽企业重金招聘Python工程师标准>>> 前言: 由于在平时的工作中,线上服务器是分布式多台部署的,经常会面临解决分布式场景下数据一致性的问题,那么就要利用分布式锁来解 ...

  9. 分布式场景下的并发安全问题,收割快手,字节,百度,美团的Offer之旅

    ​ try { ​ lock.lock(); ​ SimpleDateFormat simpt = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss&quo ...

最新文章

  1. [云炬创业基础笔记]第七章创业资源测试2
  2. Linux开机启动的步骤
  3. 手把手教你如何把本地文件传到服务器,如何映射
  4. 使用tcl 创建vivado工程
  5. jquery 获取 选中的radio的值
  6. 高中计算机学考操作excel,高中信息技术学业水平考试Word、Excel操作题考点总结...
  7. 神奇的识别图片文字代码
  8. 确定你的台式计算机支持的内存类型,如何区分内存类型及查看内存的兼容性
  9. dm385和8127的区别
  10. 1.23英文题面翻译
  11. php-fpm的几种重启方式
  12. c语言数字的写法田字格,正确书写数字1-10的方法,实用!
  13. oracle存储过程之关键词dual
  14. OpenCV 学习笔记03 凸包convexHull、道格拉斯-普克算法Douglas-Peucker algorithm、approxPloyDP 函数...
  15. 201571030131/201571030111《小学四则运算练习软件软件需求说明》结对项目报告
  16. 【计算机组成原理】计算机系统概述总结——基本知识要点汇总
  17. springboot 集成xxl-job 定时任务管理平台
  18. 人民币小写转换成大写
  19. 《活动公告》 熊岳海滨之夏
  20. CentOS 7一键安装Seafile搭建私有云存储

热门文章

  1. Chrome控制台实用指南
  2. GPRS流量计算方法(TCP/IP)
  3. Log4j使用详解(log4j.XML格式)——整理
  4. 先搞清楚了任务究竟是什么再说
  5. XSLT教程 [转]
  6. 架构师和产品经理的区别
  7. dotnet core高吞吐Http api服务组件FastHttpApi
  8. BFC与垂直外边距折叠笔记
  9. Skype for business混合部署系列之二自定义拓扑信息
  10. ActiveMQ消息的延时和定时投递