最近突然感觉:很多软件、硬件在设计上是有root reason的,不是by desgin如此,而是解决了那时、那个场景的那个需求。一旦了解后,就会感觉在和设计者对话,了解他们的思路,学习他们的方法,思维同屏:活到老学到老。
1.1 Consumer Queue Offset是连续的吗, 为什么?
1.2 Commit Log Offset是连续的吗, 为什么?
1.3 Java写的文件,默认是大端序还是小端序,为什么?
在大家思考之际, 我们回想下commit log是怎么分布的呢?
在Broker配置的存储根目录下,通过查看Broker实际生成的commit log文件可以看到类似下面的数据文件分布:
可以看到,真实的存储文件有多个, 每一个都是以一串类似数字的字符串作为文件名的,并且大小1G。
我们结合源码可以知道,实际的抽象模型如下:
由上图得知:
说明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
我们看到Commit Log文件中有很多个消息,按照既定的协议存储的,那具体协议是什么呢, 你是怎么知道的呢?
关于Commit Log存储协议,我们问了下ChatGPT, 它是这么回复我的,虽然不对,但是这个回复格式和说明已经非常接近答案了。
我整理后, 如下图;
说明1:我整理后的消息协议编号和代码中不是一致的,代码中只是标明了顺序, 真实物理文件中的存储协议会更详细。
说明2:在我写的《RocketMQ分布式消息中间件:核心原理与最佳实践》中,这个图缺少了Body内容,这里加了,也更详细的补充了其他数据。
这里有几个问题需要说明下:
我们看到这个协议后,如何证明你的物理文件就是按照这个协议写的呢?
RocketMQ是用java写的,根据上文描述的存储协议,我用Golang编写了一个工具,可以解开Commit Log和Cosumer Queue,代码地址:https://github.com/rmq-plus-plus/rocketmq-decoder。
这个工具目前支持2个功能:
在Golang中没有依赖RocketMQ的任何代码,纯粹是依靠协议解码。
这里贴了一段golang中解析Commit Log Offset的例子:在java中这个offset是一个long类型,占用8个字节。
在golang中,读取8个字节长度的数据,并且按照大端序解码为int64,就可以得到正常的Commit Log Offset。
我跑了一个demo结果,大家参考:
以下为个人见解,大家参考:
1.1 Consumer Queue Offset是连续的吗, 为什么?
是连续的。
consumer queue offset,是指每个queue中索引消息的下标,下标当然是连续的。消费者也是利用了这个连续性,避免消费位点提交空洞的。
每个索引消息占用相同空间,都是20字节,结构如下:
这里物理位点也就是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 删除。