RocketMQ 消息存储机制 CommitLog和ConsumerQu

Rocketmq在消息存储方面做了很多的优化,那也是为了提升rocketmq的性能。首先要知道消息不会保存在内存里面,如果生产者发送的消息是保存在内存里面,那很有可能消息会丢失。

所以Rocketmq和kafka一样会把消息保存在磁盘文件当中,既然保存在文件当中就要考虑对文件读写性能的问题。

生产者去发送消息,生产者发送的消息一定是保存在commitlog这个文件里面。

之前不是说的生产者发送的消息保存在某个主题,某个队列里面?实际上这只是映射成逻辑的关系。

所有的消息都是在一个文件里面,commitlog里面,当然如果这个文件存储不下,还会有另外一个commitlog文件。

所以生产者所有的消息都会保存在这个文件里面。保存在这个文件里面对于消费者来说,它要去消费某个主题。生产者可能会往t1这个主题去发,t2这个主题也会去发,也可能会往t3主题去发。在这个文件当中会有很多主题的消息,对于消费者去这个文件检索t1主题的消息其实是性能比较差的。

Rocketmq会去做这么一件事情,它会去创建逻辑上的一些划分,比如生产者负载均衡的往队列上面去发。但是保存依赖是保存在commitlog里面,这个时候为了提高消费者的性能,这个时候就会有逻辑上的队列叫做consumerquenue0,那这里面保存了什么?

ConsumeQueue 0 1 2 3

消息消费队列,引⼊的⽬的主要是提⾼消息消费的性能,由于RocketMQ是基于主题topic的订阅模式,消息消费是针对主题进⾏的,如果要遍历commitlog⽂件中根据 topic检索消息是⾮常低效的。Consumer即可根据ConsumeQueue来查找待消费的消息。
其中,ConsumeQueue(逻辑消费队列)作为消费消息的索引,保存了指定Topic下的队列消息在CommitLog中的起始物理偏移量offset,消息⼤⼩size和消息Tag的HashCode值。consumequeue⽂件可以看成是基于topic的commitlog索引⽂ ,故consumequeue⽂件夹的组织⽅式如下:

topic/queue/file三层组织结构,具体存储路径为:$HOME/store/consumequeue/{topic}/{queueId}/{fileName}。同样 consumequeue⽂件采取定⻓设计,每⼀个条⽬共20个字节,分别为8字节的commitlog物理偏移量、4字节的消息⻓度、8字节tag hashcode,单个⽂件由30W个 条⽬组成,可以像数组⼀样随机访问每⼀个条⽬,每个ConsumeQueue⽂件⼤⼩约 5.72M;

也就是所有的数据都在commitlog里面,怎么知道topic1 里面的messagequenue0的数据是哪些?因为所有的数据都在commitlog里面。所以consumer quenue0告诉你了topic1里面messagequenue0里面的数据在commitlog当中起始的偏移量是多少。

在消费者进行消费的时候,每次消费完它也上报消费者的偏移量,也就是哪些数据 topic1里面messagequenue0里面哪些数据已经被消费者消费了。也需要把这个告知Rocketmq。

因为消费者挂掉,那么同组的消费者可以接着上个消费者的位置继续消费。所以还会保存consumer的offset。

所有的消息都在commitlog里面,我们知道这些消息在topic里面的某个队列里面。虽然保存在commitlog里面,但是实际上会进行逻辑的划分。划分在topic里面某个message quenue里面。

具体的offset,在哪个位置,保存在对应的consumerquenue0 1 2里面,这样消费者在消费的时候效率明显得到了提升。

CommitLog
消息主体以及元数据的存储主体,存储Producer端写⼊的消息主体内容,消息内容不是定⻓的。单个⽂件⼤⼩默认1G ,⽂件名⻓度为20位,左边补零,剩余为起始偏 移量,⽐如00000000000000000000代表了第⼀个⽂件,起始偏移量为0,⽂件⼤⼩
为1G=1073741824;当第⼀个⽂件写满了,第⼆个⽂件为00000000001073741824, 起始偏移量为1073741824,以此类推。消息主要是顺序写⼊⽇志⽂件,当⽂件满 了,写⼊下⼀个⽂件;

在broker里面配置了commitlog位置和consumerquenue位置

复制代码
#commitLog存储路径
storePathCommitLog=/usr/local/rocketmq/broker-a-master/store/commitlog
#消费队列存储路径
storePathConsumeQueue=/usr/local/rocketmq/broker-a-master/store/consumequeue


[root@localhost commitlog]# pwd
/usr/local/rocketmq/broker-a-master/store/commitlog
[root@localhost commitlog]# ls
00000000000000000000

[root@localhost commitlog]# ll
total 860
-rw-r--r--. 1 root root 1073741824 Aug  9 09:46 00000000000000000000

所有的消息都会保存在000000这个文件里面,这个文件大小是1G,当这个文件保存的数据超过了这个文件大小,那么就会创建出新的文件来。

consumer quenue里面有我们创建的topic,

复制代码
[root@localhost ~]# ls  /usr/local/rocketmq/broker-a-master/store/consumequeue
TopicTest

可以看到这个主题对应的了4个队列

复制代码
[root@localhost consumequeue]# cd TopicTest/
[root@localhost TopicTest]# ls
0  1  2  3

0里面也放了一些文件,这个文件其实就是consumerquenue0,

复制代码
[root@localhost TopicTest]# ll 0
total 24
-rw-r--r--. 1 root root 6000000 Aug  9 09:46 00000000000000000000
[root@localhost TopicTest]# ll 1
total 24
-rw-r--r--. 1 root root 6000000 Aug  9 09:46 00000000000000000000

其实就是这个文件,这个文件里面放了相应的偏移量,这里只会保存具体偏移量的数据。

在发送消息的时候要往topic1上的messagequenue0上面发,但是都保存在这个commitlog里面。消息的逻辑位置在具体的物理上的位置在哪?那么就在consumerquenue0的文件里面,

相关推荐
syty20201 天前
kafka vs rocketmq
分布式·kafka·rocketmq
菠菠萝宝1 天前
【Java八股文】13-中间件面试篇
java·docker·kafka·rabbitmq·canal·rocketmq·es
承悦赋2 天前
微服务通信:5大消息队列横向对比
微服务·架构·kafka·rabbitmq·rocketmq
云闲不收3 天前
RocketMQ基础以及和 Kafka 有什么区别
分布式·kafka·rocketmq
无名客03 天前
RocketMQ相对于RabbitMQ 的优势
分布式·rabbitmq·rocketmq
用户9446814013503 天前
【RocketMQ长文 从入门到精通(中)】工作原理
消息队列·rocketmq
用户9446814013503 天前
【RocketMQ长文 从入门到精通(上)】基础概念
rocketmq
若水不如远方6 天前
RocketMQ消费流程深度解析:从原理到实践
后端·rocketmq
Apache_RocketMQ8 天前
Apache RocketMQ 打破锁性能瓶颈之道
云原生·消息队列·rocketmq
阿里云云原生11 天前
海量接入、毫秒响应:易易互联携手阿里云构筑高可用物联网消息中枢
rocketmq