当我们用RocketMQ发送信息的时候通常都会返回如下信息:

SendResult [sendStatus=SEND_OK, msgId=0A42333A0DC818B4AAC246C290FD0000, offsetMsgId=0A42333A00002A9F000000000134F1F5, messageQueue=MessageQueue [topic=topicTest1, brokerName=mac.local, queueId=3], queueOffset=4]

对于客户端来说msgId是由客户端producer自己生成的,offsetMsgId是由服务端broker生成的,其中offsetMsgId就是我们在rocketMQ控制台直接输入查询的那个messageId。

下面就来介绍一下这两个ID的生成算法:

msgId:

以下是RocketMQ部分源码的节选

      初始化参数LEN,FIX_STRING,COUNTER

      初始化buffer

      设置开始时间

      字节转string工具方法

    最终生成msgId

其中createUniqId就是最终生成msgId方法。除些之外的方法者是createUniqId调用或者被间接调用的方法,这些方法实现也比较简单。这里就不一一解释了~

StringBuilder sb = new StringBuilder(LEN * 2);

由此可知msgId的长度是LEN * 2 = 16 * 2 = 32;

     设time = 当前时间 - 本月开始时间(ms);

     从代码得到 FIX_STRING = ip + 进程pid + MessageClientIDSetter.class.getClassLoader().hashCode();

     createUniqIDBuffer 加入time 和 counter 因子。

    最终得到msgId的生成因子是:   ip + 进程pid + MessageClientIDSetter.class.getClassLoader().hashCode() + time + counter(AtomicInteger自增变量)

     最后调用bytes2string进行十六进制的移位和编码就产生了我们的msgId。

那我们来分析一下这个算法:

对于每个producer实例来说ip都是唯一的,所以不同producer生成的msgId是不会重复的。对于producer单个实例来说的区分因子是:time + counter。首先应用不重启的情况下msgId是保证唯一性的,应用重启了只要系统的时钟不变msgId也是唯一的。所以只要系统的时钟不回拨我们就可以保证msgId的全局唯一。

有人也许会说应用运行了一个月再进行重启msgId就会重复了。从生成算法上来说是的!但是MQ的message是有时效性的,有效期是72小时也就是3天。每天的凌晨4点rocketMQ会把过期的message清除掉。所以msgId也是保证全局唯一的。

offsetMsgId:

 broker端生成的offsetMsgId就比较简单了,直接就是主机ip + 物理分区的offset,再调用UtilAll.bytes2string进行移位转码就完成了,是不是很简单粗爆?!

      以上就是RocketMQ生成msgId和offsetMsgId的生成算法。通过阅读文章我们除了了解RocketMQ生成msgId的方式之外,在日常项目中如果有遇到类似遇到生成全局唯一key场景时是不是也可以借鉴一下RocketMQ的思路?如果文章有什么不理解的地方欢迎大家提出宝贵的意见,也欢迎大家多多交流~~~~

RocketMQ msgId生成算法的更多相关文章

  1. 一个UUID生成算法的C语言实现 --- WIN32版本 .

    一个UUID生成算法的C语言实现——WIN32版本   cheungmine 2007-9-16   根据定义,UUID(Universally Unique IDentifier,也称GUID)在时 ...

  2. 分布式全局不重复ID生成算法

    分布式全局不重复ID生成算法 算法全局id唯一id  在分布式系统中经常会使用到生成全局唯一不重复ID的情况.本篇博客介绍生成的一些方法. 常见的一些方式: 1.通过DB做全局自增操作 优点:简单.高 ...

  3. C++ 基于凸包的Delaunay三角网生成算法

    Delaunay三角网,写了用半天,调试BUG用了2天……醉了. 基本思路比较简单,但效率并不是很快. 1. 先生成一个凸包: 2. 只考虑凸包上的点,将凸包环切,生成一个三角网,暂时不考虑Delau ...

  4. C++ 凸包生成算法

    由于我的极差记忆力,我打算把这个破玩意先记下来.因为以后会有改动(Delaunay三角网生成算法),我不想把一个好的东西改坏了... 好吧-- 凸包生成算法,: 1.先在指定的宽(width)高(he ...

  5. 分布式系统的唯一id生成算法你了解吗?

    在分库分表之后你必然要面对的一个问题,就是id咋生成? 因为要是一个表分成多个表之后,每个表的id都是从1开始累加自增长,那肯定不对啊. 举个例子,你的订单表拆分为了1024张订单表,每个表的id都从 ...

  6. 转:体积阴影(Shadow Volumes)生成算法

    下面以最快的速度简单谈谈阴影生成技术,目前普遍采用的一般有三种:Planar Shadow.Shadow Mapping和Shadow Volume,前者类似投影,计算最简单,缺点只能绘制抛射在平面上 ...

  7. STL_算法_04_算术和生成算法

    ◆ 常用的算术和生成算法: 1.1.求和( accumulate 是求和的意思)(对指定范围内的元素求和,然后结果再加上一个由val指定的初始值.) T accumulate(iteratorBegi ...

  8. ES批量索引写入时的ID自动生成算法

    对bulk request的处理流程: 1.遍历所有的request,对其做一些加工,主要包括:获取routing(如果mapping里有的话).指定的timestamp(如果没有带timestamp ...

  9. O(n)线性空间的迷宫生成算法

    之前所有的迷宫生成算法,空间都是O(mn),时间同样是O(mn),时间上已经不可能更优化, 于是,我就从空间优化上着手,研究一个仅用O(n)空间的生成算法. 我初步的想法是,每次生成一行,生成后立即输 ...

随机推荐

  1. pip 报错

    pip 安装 初始化系统 安装PiP 问题? 依赖包:yun install wget gcc gcc-c++ -y python 环境 wget http://www.python.org/ftp/ ...

  2. Android五种数据存储方式

    android 五种数据存储 :SharePreferences.SQLite.Contert Provider.File.网络存储 Android系统提供了四种存储数据方式.分别为:SharePre ...

  3. python内存数据库pydblite

    Pure-Python engine 最近由于项目开发中发现python informixDB模块对多线程的支持非常不好,当开启两个线程同时连接informix数据库的时候,数据库会报错,显示SQL ...

  4. route 的标志位

    linux下利用route命令查看当前路由信息时,会打印如下信息: root@root:/# route Kernel IP routing tableDestination     Gateway  ...

  5. 转载:获取Nginx源码(1.3.5)《深入理解Nginx》(陶辉)

    原文:https://book.2cto.com/201304/19616.html 可以在Nginx官方网站(http://nginx.org/en/download.html)获取Nginx源码包 ...

  6. 04-Bootstrap的插件

    1.下拉菜单 代码如下: <div class="dropdown"> <button class="btn btn-default dropdown- ...

  7. 中文多分类 BERT

    直接把自己的工作文档导入的,由于是在外企工作,所以都是英文写的 Steps: git clone https://github.com/google-research/bert prepare dat ...

  8. ExtJs常用布局--layout详解(含实例)

    序言: 笔者用的ExtJs版本:ext-3.2.0 ExtJs常见的布局方式有:border.form.absolute.column.accordion.table.fit.card.anchor ...

  9. webpack 3之hash、chunkhash和contenthash三者的区别

    在使用webpack 3中,文件名的hash值可以有三种hash生成方式,那具体使用哪一种呢? 1.hash 如果都使用hash的话,所有文件的hash都是一样的,而且每次修改任何一个文件,所有文件名 ...

  10. python+selenium六:等待相关

    显式等待(sleep): 固定的等待(死等),不管页面有没有加载完,都等设置的时间过了再做下一步操作 隐式等待 全局生效,只写一次即可(仅当前页面),缺点:如果页面一直转圈,如:js出错将等待到所设置 ...