金医疗医疗转板申请已获批准,即将在联交所主板上市
06-17
最近突然感觉:很多软件、硬件都是有根本原因的,不是为了设计,而是为了解决那个时候那个场景的需求。一旦你了解了它们,你就会感觉自己在和设计师交谈,了解他们的想法,学习他们的方法,同屏思考:活到老,学到老。
1、我们思考一下 1.1 Consumer Queue Offset 是否连续?为什么? 1.2 Commit Log Offset是否连续?为什么? 1.3 用Java编写的文件默认是big-endian或little-endian。为什么? 2、Commit Log的实际分布 大家在思考的同时,我们来回忆一下commit log是如何分布的?在Broker配置的存储根目录下,通过查看Broker实际生成的提交日志文件,可以看到类似如下的数据文件分布。
:可以看到Broker的真实数据文件存储分布。真实存储有多个文件,每个文件都有一个类似于数字的字符串作为文件名,大小为1G。
从源码中我们可以知道,实际的抽象模型如下: Commit Log存储文件分布抽象由上图可知:Commit Log是一类文件的名称。其实Commit Log文件有很多,每一个都可以称为Commit Log。
文档。如图所示,一共有T个Commit Log文件,从过去到现在按照创建时间排列。
每个Commit Log文件按照消息写入的顺序保存消息,并且始终写入创建时间最长的文件,并且同一时间只能有一个线程写入。如图,第1个文件,1,2,3,4...表示该文件中的消息条数。
可以看到第1条消息是第1个Commit Log文件的最后一条消息,第1条消息是第1个Commit Log文件。 2 个提交日志的第一条消息。
注1:每个Commit Log文件中所有消息实际占用的存储空间<=1G。我们自己思考一下造成这个问题的原因。
注2:每次写入Commit Log,RocketMQ都会锁定它。请参阅代码片段。
Log文件中有很多消息,这些消息是按照既定的协议存储的。具体协议是什么?你怎么知道的? 3. Commit Log 存储协议 关于 Commit Log 存储协议,我们询问了 ChatGPT,这是它给我的答复。
虽然不正确,但是回复格式和描述都非常接近答案。ChatGPT回复我们看了源码,详细解释了:我整理了Log存储协议,如下图;我理解的Commit Log存储协议的描述1:我整理出来的消息协议号与代码不一致,只是在代码中标注了顺序,真实物理文件中的存储协议会更详细。
注2:我写的《RocketMQ分布式消息中间件:核心原理与最佳实践》中,这张图缺少Body内容。这里补充一下,其他数据补充的更详细。
这里需要说明几个问题: 二进制协议是有字节序的,也就是常说的大端序和小端序。这里我就不详细阐述大端和小端了。
有兴趣的同学可以google或者在ChatGPT上提问。答案肯定会比我说的更好。
在Java中,一个byte占1个字节,一个int占4个字节,一个short占2个字节,一个long占8个字节。 Host的编码并不是简单地将IP:Port作为字符串直接转为字节数组,而是将每个数字按顺序编码为一个字节。
这将在下一节 Golang 代码中进行解释。在扩展信息的编码中,使用不可见字符作为划分,因此扩展字段键值不能包含这两个不可见字符。
具体是哪两个呢?你能找到他们吗?我们看到这个协议之后,如何证明你的实体文件是按照这个协议写的呢? 4.使用Golang解锁RocketMQ Commit LogRocketMQ是用java编写的。根据上面描述的存储协议,我使用Golang编写了一个可以解锁Commit Log和Cosumer Queue的工具。
代码地址:Log站点,直接解析Log中的Commit消息并打印。指定消费位置,首先解析Consumer Queue,获取Commit Log Offset,然后根据Commit Log Offset直接解析Commit Log,并打印。
Golang中没有依赖RocketMQ的代码,纯粹依赖协议解码。 golang-import这里贴了一个golang中解析Commit Log Offset的例子:在Java中,这个offset是一个long类型,占用8个字节。
在golang中,通过读取8字节数据并按照big-endian顺序解码为int64,就可以得到正常的Commit Log Offset。我运行了Golang-demo的演示结果。
请参考:阅读consumer-queue-commit-log5。为了回答最初的问题,以下是我个人的看法。
请参考:1.1 Consumer Queue Offset 是否连续?为什么?是连续的。消费者队列偏移量是指索引消息在每个队列中的下标。
下标当然是连续的。消费者还利用这种连续性来避免空消费网站提交。
每个索引消息占用相同的空间,即20字节。结构如下:消费者队列索引消息结构。
这里的物理位置是提交日志偏移量。 1.2 Commit Log Offset是否连续?为什么?不是连续的。
Commit Log Offset是指每条消息在所有Commit Log文件中的字节偏移量。每条消息的大小是不确定的,所以Commit Log Offset,即字节偏移量必须不同。
。我们可以知道,每两个偏移量之差的绝对值就是前一条消息的总长度(以字节为单位)。
并且上图中的“Commit Log存储文件分布抽象”存在一个误解。每个小方块的大小其实是不一样的。
1.3 用Java编写的文件默认是big-endian或little-endian。为什么?大尾数。
字节顺序实际上有两种:数据存储顺序和网络传输顺序。 Java中默认使用的big-endian顺序与网络传输保持一致,这样方便编码和解码。
每个网络传输层数据报文的第一个字节表示后续数据使用什么协议进行传输。这样,数据接收方收到数据时,首先按照字节顺序解析协议,然后按照协议对后续数据进行解码。
符合人类思考和解决问题方式的字节序列。以上是我的理解。
如果有什么问题可以加我微信聊。微信二维码讨论注意:由于RocketMQ的某些版本可能有所不同,本文讨论4.9.3版本。
你可以参考这个方法来了解5.0甚至其他版本中其他数据文件的存储协议格式。
版权声明:本文内容由互联网用户自发贡献,本站不拥有所有权,不承担相关法律责任。如果发现本站有涉嫌抄袭的内容,欢迎发送邮件 举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。
标签:
相关文章
06-17
06-18
06-21
06-21
最新文章
【玩转GPU】ControlNet初学者生存指南
【实战】获取小程序中用户的城市信息(附源码)
包雪雪简单介绍Vue.js:开学
Go进阶:使用Gin框架简单实现服务端渲染
线程池介绍及实际案例分享
JMeter 注释 18 - JMeter 常用配置组件介绍
基于Sentry的大数据权限解决方案
【云+社区年度征文集】GPE监控介绍及使用