RocketMQ 消息存储机制 CommitLog和ConsumerQu
Rocketmq在消息存储方面做了很多的优化,那也是为了提升rocketmq的性能。首先要知道消息不会保存在内存里面,如果生产者发送的消息是保存在内存里面,那很有可能消息会丢失。
所以Rocketmq和kafka一样会把消息保存在磁盘文件当中,既然保存在文件当中就要考虑对文件读写性能的问题。
生产者去发送消息,生产者发送的消息一定是保存在commitlog这个文件里面。
之前不是说的生产者发送的消息保存在某个主题,某个队列里面?实际上这只是映射成逻辑的关系。
所有的消息都是在一个文件里面,commitlog里面,当然如果这个文件存储不下,还会有另外一个commitlog文件。
所以生产者所有的消息都会保存在这个文件里面。保存在这个文件里面对于消费者来说,它要去消费某个主题。生产者可能会往t1这个主题去发,t2这个主题也会去发,也可能会往t3主题去发。在这个文件当中会有很多主题的消息,对于消费者去这个文件检索t1主题的消息其实是性能比较差的。
Rocketmq会去做这么一件事情,它会去创建逻辑上的一些划分,比如生产者负载均衡的往队列上面去发。但是保存依赖是保存在commitlog里面,这个时候为了提高消费者的性能,这个时候就会有逻辑上的队列叫做consumerquenue0,那这里面保存了什么?
ConsumeQueue 0 1 2 3
其中,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里面,这样消费者在消费的时候效率明显得到了提升。
在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的文件里面,