前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >重新理解RocketMQ Commit Log存储协议

重新理解RocketMQ Commit Log存储协议

原创
作者头像
小伟
修改于 2023-04-06 10:01:22
修改于 2023-04-06 10:01:22
5.4K0
举报
文章被收录于专栏:魔都程序缘魔都程序缘

最近突然感觉:很多软件、硬件在设计上是有root reason的,不是by desgin如此,而是解决了那时、那个场景的那个需求。一旦了解后,就会感觉在和设计者对话,了解他们的思路,学习他们的方法,思维同屏:活到老学到老。

1. 大家思考

1.1 Consumer Queue Offset是连续的吗, 为什么?

1.2 Commit Log Offset是连续的吗, 为什么?

1.3 Java写的文件,默认是大端序还是小端序,为什么?

2. Commit Log真实分布

在大家思考之际, 我们回想下commit log是怎么分布的呢?

在Broker配置的存储根目录下,通过查看Broker实际生成的commit log文件可以看到类似下面的数据文件分布:

Broker真实数据文件存储分布
Broker真实数据文件存储分布

可以看到,真实的存储文件有多个, 每一个都是以一串类似数字的字符串作为文件名的,并且大小1G。

我们结合源码可以知道,实际的抽象模型如下:

Commit Log存储文件分布抽象
Commit Log存储文件分布抽象

由上图得知:

  • Commit Log是一类文件的称呼,实际上Commit Log文件有很多个, 每一个都可以称为Commit Log文件。 如图中表示了总共有T个Commit Log文件,他们按照由过去到现在的创建时间排列。

  • 每个Commit Log文件都保存消息, 并且是按照消息的写入顺序保存的,并且总是在写创建时间最大的文件,并且同一个时刻只能有一个线程在写。 如图中第1个文件,1,2,3,4...表示这个文件的第几个消息,可以看到第1234个消息是第1个Commit Log文件的最后一个消息,第1235个消息是第2个Commit Log的第1个消息。

说明1:每个Commit Log文件里的全部消息实际占用的存储空间大小<=1G。这个问题大家自行思考下原因。

说明2:每次写Commit Log时, RocketMQ都会加锁,代码片段见 https://github.com/apache/rocketmq/blob/7676cd9366a3297925deabcf27bb590e34648645/store/src/main/java/org/apache/rocketmq/store/CommitLog.java#L676-L722

append加锁
append加锁

我们看到Commit Log文件中有很多个消息,按照既定的协议存储的,那具体协议是什么呢, 你是怎么知道的呢?

3. Commit Log存储协议

关于Commit Log存储协议,我们问了下ChatGPT, 它是这么回复我的,虽然不对,但是这个回复格式和说明已经非常接近答案了。

ChatGPT回复
ChatGPT回复

我们翻看源码,具体说明下:https://github.com/apache/rocketmq/blob/rocketmq-all-4.9.3/store/src/main/java/org/apache/rocketmq/store/CommitLog.java#L1547-L1587

Commit Log存储协议
Commit Log存储协议

我整理后, 如下图;

我理解的Commit Log存储协议
我理解的Commit Log存储协议

说明1:我整理后的消息协议编号和代码中不是一致的,代码中只是标明了顺序, 真实物理文件中的存储协议会更详细。

说明2:在我写的《RocketMQ分布式消息中间件:核心原理与最佳实践》中,这个图缺少了Body内容,这里加了,也更详细的补充了其他数据。

这里有几个问题需要说明下:

  1. 二进制协议存在字节序,也就是常说的大端、小端。 大小端这里不详细说明感兴趣的同学自己google或者问题ChatGPT,回答肯定比我说的好。
  2. 在java中, 一个byte占用1个字节,1个int占用4个字节,1个short占用2个字节,1个long占用8个字节。
  3. Host的编码并不是简单的把IP:Port作为字符串直接转化为byte数组,而是每个数字当作byte依次编码。在下一节的Golang代码中会说明。
  4. 扩展信息的编码中,使用了不可见字符作为分割,所以扩展字段key-value中不能包含那2个不可见字符。 具体是哪2个,大家找找?

我们看到这个协议后,如何证明你的物理文件就是按照这个协议写的呢?

4. 用Golang解开RocketMQ Commit Log

RocketMQ是用java写的,根据上文描述的存储协议,我用Golang编写了一个工具,可以解开Commit Log和Cosumer Queue,代码地址:https://github.com/rmq-plus-plus/rocketmq-decoder

这个工具目前支持2个功能:

  1. 指定Commit Log位点,直接解析Commit Log中的消息,并且打印。
  2. 指定消费位点,先解析Consumer Queue,得到Commit Log Offset后,再根据Commit Log Offset直接解析Commit Log,并且打印。

在Golang中没有依赖RocketMQ的任何代码,纯粹是依靠协议解码。

golang-import
golang-import

这里贴了一段golang中解析Commit Log Offset的例子:在java中这个offset是一个long类型,占用8个字节。

在golang中,读取8个字节长度的数据,并且按照大端序解码为int64,就可以得到正常的Commit Log Offset。

Golang-demo
Golang-demo

我跑了一个demo结果,大家参考:

读取consumer-queue-commit-log
读取consumer-queue-commit-log

5. 回答最初的问题

以下为个人见解,大家参考:

1.1 Consumer Queue Offset是连续的吗, 为什么?

是连续的。

consumer queue offset,是指每个queue中索引消息的下标,下标当然是连续的。消费者也是利用了这个连续性,避免消费位点提交空洞的。

每个索引消息占用相同空间,都是20字节,结构如下:

consumer-queue索引消息结构
consumer-queue索引消息结构

这里物理位点也就是Commit Log Offset。

1.2 Commit Log Offset是连续的吗, 为什么?

不是连续的。

Commit Log Offset是指的每个消息在全部Commit Log文件中的字节偏移量, 每个消息的大小是不确定的,所以Commit Log Offset,也即是字节偏移量肯定是不一样的。

并且可以知道,每两个偏移量的差的绝对值就是前一个消息的消息字节数总长度。

并且上文中图 “Commit Log存储文件分布抽象”中的有误解,每个小方格的大小其实是不一样的。

1.3 Java写的文件,默认是大端序还是小端序,为什么?

大端序。字节序其实有数据存储顺序和网络传输顺序两种,java中默认用的大端序,保持和网络传输一样,这样方便编解码。

每段网络传输层的数据报文最前面的字节是表达后面的数据是用什么协议传输的,这样数据接收者在接受数据时, 按照字节顺序,先解析协议,再根据协议解码后面的字节序列,符合人类思考和解决问题的方式。

以上是我的理解,有任何问题,加我微信细聊。

微信二维码
微信二维码

讨论说明:由于RocketMQ一些版本可能有差异,本文在4.9.3版本下讨论,大家可以参考这个方法,解开5.0甚至其他版本,其他数据文件的存储协议格式。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
BM3D图像去噪算法原理及代码详解
BM3D是2007年TIP的文章,题目是Image denoising by sparse 3D transform-domain collaborative ltering,论文、项目的地址是http://www.cs.tut.fi/~foi/GCF-BM3D/,提供matlab代码。 处理灰度图的BM3D以及它的变体CBM3D(彩色图)、VBM3D(时域)是图像去噪领域公认的去噪效果(PSNR)最好的,而BM4D、VBM4D等也都是沿袭BM3D的基于块处理(block-wise estimate)的思想,但其计算时间复杂度极大,或许只能用于离线处理(offline),当然后续有文章进行优化(代码、算法),这里就不再提及。
全栈程序员站长
2022/08/14
2.2K0
BM3D图像去噪算法原理及代码详解
BM3D图像去噪算法
一种非局部去噪方法Non-local method[1],可以归类到spatial method中,另外用的比较多的还有transform method,基于transform method的方法在image denoise中也取得了很好的效果,不过理论阐述会比较繁琐,如BLS-GSM-Wavelet。
全栈程序员站长
2022/08/14
9220
BM3D图像去噪算法
传统图像降噪算法之BM3D原理详解
图像降噪是一个十分具有实用价值的研究方向,因为噪声总是无处不在的。当处于比较昏暗的环境时,噪声将极大地影响着我们所拍摄的图像。如今,随着深度学习算法以及相关硬件的不断发展,深度卷积网络同样在图像降噪领域占据了主流,并且代表了该领域最优异的成绩。但是,深度神经网络同样有着其缺点,例如模型过于庞大而计算复杂度过高,以及缺乏一些理论上的解释性,当然这些缺点正不断地得到弥补。为了更好地理解图像降噪的基本原理,我们有必要回过头来仔细研读一些传统算法的具体思路,了解其所使用基本理论依据,以及一些巧妙的改进方法。在这些传统降噪算法中,最经典而强大的莫过于 BM3D 了。这篇文章将全面地对其原理进行解读,并且对其论文中一些没有提及的细节进行补充,让各位读者能够更加轻松地理解其算法的内核。在开始这篇文章之前,本人建议大家可以先看一下以下的文章,主要是对本文中一些需要用到但是为了节省篇幅而没有细讲的基本原理进行补充:
全栈程序员站长
2022/06/26
2.1K0
传统图像降噪算法之BM3D原理详解
BM3D的学习与Matlab实现「建议收藏」
BM3D是2007年TIP的文章,题目是《Image Denoising by Sparse 3-D Transform-Domain Collaborative Filtering》。最近想尝试一下图像去噪,看看能否应用到项目中,顺便测试了一下效果,结果不是太理想,主要问题是时间,去噪效果还是可以的。担心以后找起来(实现)麻烦,就当做个笔记了。
全栈程序员站长
2022/08/15
1.5K0
BM3D的学习与Matlab实现「建议收藏」
BM3D(Block-Matching and 3D filtering)读后感[通俗易懂]
BM3D是2007年TIP的文章,题目是Image denoising by sparse 3D transform-domain collaborative ltering,论文、项目的地址是http://www.cs.tut.fi/~foi/GCF-BM3D/,提供matlab代码;http://www.ipol.im/pub/art/2012/l-bm3d/为C++的实现,这篇论文里面有对BM3D实现的更为详细的说明。
全栈程序员站长
2022/06/26
1.6K0
BM3D(Block-Matching and 3D filtering)读后感[通俗易懂]
通俗语言说BM3D
随着友商某以摄像著称的旗舰机型的发布,其SOC中ISP5.0采用的所谓单反级降噪算法BM3D一下火热起来,本文试图用尽量通俗易懂的语言从算法原理的角度揭开BM3D算法的神秘面纱。
全栈程序员站长
2022/06/26
3.2K2
通俗语言说BM3D
BM3D算法「建议收藏」
BM3D(Block-matching and 3D filtering,3维块匹配滤波) 2007-TIP-Image denoising by sparse 3D transform-domain collaborative ltering
全栈程序员站长
2022/06/26
1.4K0
BM3D算法「建议收藏」
Transfer Learning
通过网络上收集宝可梦的图片,制作图像分类数据集。我收集了5种宝可梦,分别是皮卡丘,超梦,杰尼龟,小火龙,妙蛙种子
mathor
2020/02/17
4580
深度学习实战之手写签名识别(100%准确率、语音播报)
在完成了上述的环境搭建后,即可进入到准备阶段了。这里准备的有数据集的准备、以及相关代码的主备。
陶陶name
2022/05/13
1.7K0
气象编程 | 科学计算库Scipy简易入门
Scipy是一个用于数学、科学、工程领域的常用软件包,可以处理插值、积分、优化、图像处理、常微分方程数值解的求解、信号处理等问题。它用于有效计算Numpy矩阵,使Numpy和Scipy协同工作,高效解决问题。
气象学家
2020/07/20
1.7K0
气象编程 | 科学计算库Scipy简易入门
8个有用的 CSS 技巧:视差图像,sticky footer 等等
CSS是一种独特的语言。乍一看,这似乎很简单,但是,某些在理论上看起来很简单的效果在实践中往往不那么明显。
前端小智@大迁世界
2019/04/18
1.3K0
『跟着雨哥学AI』系列之六:趣味案例——基于U-Net的宠物图像分割
“跟着雨哥学AI”是百度飞桨开源框架近期针对高层API推出的系列课。本课程由多位资深飞桨工程师精心打造,不仅提供了从数据处理、到模型组网、模型训练、模型评估和推理部署全流程讲解;还提供了丰富的趣味案例,旨在帮助开发者更全面清晰地掌握百度飞桨框架的用法,并能够举一反三、灵活使用飞桨框架进行深度学习实践。
用户1386409
2021/03/09
7720
『跟着雨哥学AI』系列之六:趣味案例——基于U-Net的宠物图像分割
手写数字识别数据集_卷积神经网络分类
使用环境:python3.8 平台:Windows10 IDE:PyCharm
全栈程序员站长
2022/10/05
8400
手写数字识别数据集_卷积神经网络分类
【YOLOv8】YOLOv8改进系列(1)----替换主干网络之EfficientViT(CVPR2023)
EfficientViT:作者是来自香港中文大学和微软研究院的研究团队。论文的主要内容是提出了一种新型的高效视觉变换器(Vision Transformer,简称ViT)模型,这种模型旨在解决传统ViT在计算成本高、不适合实时应用的问题。
HABuo
2025/02/20
4590
【YOLOv8】YOLOv8改进系列(1)----替换主干网络之EfficientViT(CVPR2023)
RT-DETR改进:Backbone改进 | EMO,结合 CNN 和 Transformer 的现代倒残差移动模块设计 | ICCV2023
本文独家改进:EMO助力RT-DETR ,替换backbone,面向移动端的轻量化网络模型——EMO:反向残差移动块(iRMB),通过堆叠不同层级的 iRMB。
AI小怪兽
2023/11/15
9950
openpose模型在AI challenge人体骨骼关键点检测的表现
因为之前正好看了CMU在CVPR2017上的论文《Realtime Multi-Person 2D Pose Estimation using Part Affinity Fields》,而且他们提供了训练好的模型。所以就直接用CMU训练的模型在AI challenge的数据集上做了测试。最后没有使用AI challenge训练集训练的模型在AI challenge上的得分是0.1667,可以看作是一个baseline。
用户7043923
2020/03/12
1.2K0
【YOLOv8】YOLOv8改进系列(10)----替换主干网络之UniRepLKNet
论文介绍了一种名为 UniRepLKNet 的新型大核卷积神经网络(ConvNet),它在图像识别、音频、视频、点云、时间序列等多种模态的任务上表现出色,展示了卷积神经网络在多模态领域的巨大潜力。
HABuo
2025/03/28
1210
【YOLOv8】YOLOv8改进系列(10)----替换主干网络之UniRepLKNet
PP-Structure版面分析、表格识别使用指南
版面分析指的是对图片形式的文档进行区域划分,定位其中的关键区域,如文字、标题、表格、图片等。
算法之名
2022/10/31
6.7K0
19 | 如何可视化CT影像数据,2d和3d图像
这几天研究的跟PyTorch没啥关系,跟深度学习也没啥关系,但是跟做项目关系很大,那就是怎么把CT影像可视化。 要完美复现代码,需要安装的扩展包simpleITK,ipyvolume,diskcache,cassandra-driver
机器学习之禅
2022/07/11
1.7K0
19 | 如何可视化CT影像数据,2d和3d图像
3dreshaper_3d曲面屏幕是什么意思
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
全栈程序员站长
2022/11/04
4790
3dreshaper_3d曲面屏幕是什么意思
推荐阅读
相关推荐
BM3D图像去噪算法原理及代码详解
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档