RocketMQ:消息整体存储架构(CommitLog、ConsumeQueue)

网友投稿 1087 2022-11-10

RocketMQ:消息整体存储架构(CommitLog、ConsumeQueue)

RocketMQ:消息整体存储架构(CommitLog、ConsumeQueue)

消息存储整体架构

我们先把RocketMQ github上的消息存储图荡下来瞅瞅;

消息存储主要体现在三个文件中:​​CommitLog​​​(真正存储消息体的地方)、​​ConsumeQueue​​​(某个Topic下某个Queue的消息索引信息)、​​IndexFile​​(通过key或时间区间来查询消息的索引文件)。简版:

细版:

producer发送消息后,消息先保存到commitLog,再异步建立该条消息对应的topic + queue对应的ConsumerQueue索引。

1、CommitLog

CommitLog是消息本身、元数据的存储主体:

其存储Producer端写入的消息主体内容(包括:消息体、属性、UID等);因每条消息长度不一致,所以每个commitLog的记录也不是定长的。单个CommitLog文件大小默认最大1G, 文件名长度20位,左边补零,剩余为CommitLog中消息的起始偏移量;比如:

00000000000000000000代表了第一个文件,消息起始偏移量为0;由于1G=1073741824B;所以当第一个文件写满了之后,第二个文件名为00000000001073741824,消息起始偏移量为1073741824;CommitLog文件名以此类推。消息顺序写入日志文件,当文件满了或者不足以容纳最后一条消息之后,消息写入下一个文件。

以我的服务器为例,CommitLog日志文件存储在/root/store/commitlog文件夹中;而我的commitLog文件只有一个,所以它的文件名为:00000000000000000000。

2、ConsumeQueue

ConsumeQueue–逻辑消息消费队列,主要作用是提高消息消费的性能。

由于RocketMQ是基于主题topic的订阅模式,且消息消费也是针对主题进行的;所以如果要遍历commitlog文件,再根据topic检索消息是非常低效的。由于ConsumeQueue的存在,Consumer可以根据ConsumeQueue来查找待消费的消息。

ConsumeQueue作为消费消息的索引,保存了指定Topic下的指定队列消息在CommitLog中的起始物理偏移量offset,消息大小size和消息Tag的HashCode值。ConsumeQueue文件可以看做是基于topic的CommitLog索引文件,所以ConsumeQueue文件夹的组织方式如下:​​topic/queue/file​​三层组织结构;具体存储路径为:$HOME/store/consumequeue/{topic}/{queueId}/{fileName}。和CommitLog不同,ConsumeQueue文件采取定长设计,每一个条目共20个字节(8字节的commitlog物理偏移量、4字节的消息长度、8字节tag hashcode);​​​注意第三部分TaghashCode是服务端过滤消息的重要依据。​​单个文件最多由30W个条目组成,我们可以随机访问每一个条目,每个ConsumeQueue文件最大约5.72M。

ConsumeQueue文件存储在​​/root/store/consumequeue​​​文件夹中;由于ConsumeQueue是以Topic为维度进行划分的,所以文件夹会多一级topicName,即/root/store/consumequeue/​​saint-study-topic​​。RocketMQ默认会为每个Topic创建4个ConsumeQueue,即下图的0、1、2、3文件夹。

3、IndexFile

IndexFile(索引文件)提供了一种可以通过key或时间区间来查询消息的方法。

Index文件的存储位置是:KaTeX parse error: Undefined control sequence: \store at position 6: HOME \̲s̲t̲o̲r̲e̲\index{fileName},文件名fileName是以创建时的时间戳命名的;固定的单个IndexFile文件最大约为400M,一个IndexFile可以保存 2000W个索引;IndexFile的底层存储设计为在文件系统中实现HashMap结构,所以rocketmq的索引文件其底层实现为hash索引。

总结

RocketMQ采用的是混合型的存储结构。

Broker单个实例下所有的队列共用一个日志数据文件(CommitLog)来存储;即多个Topic的消息实体内容都存储于一个CommitLog中。 针对Producer和Consumer采用了数据和索引部分相分离的存储结构:Producer发送消息至Broker端后,Broker端使用同步或者异步的方式对消息刷盘持久化,保存至CommitLog中。Broker端启动一个后台服务线程—ReputMessageService不停地分发请求并异步构建ConsumeQueue(逻辑消费队列)和IndexFile(索引文件)数据。

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:解决在Gradle/IDEA中无法正常使用readLine的问题原因
下一篇:Maven环境安装配置和新建项目介绍
相关文章

 发表评论

暂时没有评论,来抢沙发吧~