【RocketMQ源码学习】- 5. 消息存储机制

面试官:你了解RocketMQ是如何存储消息的吗?
我:额,,,你等下,我看下这篇文字, (逃

由于这部分内容优点多,所以请哥哥姐姐们自备茶水,欢迎留言!

 

RocketMQ存储设计是高可用和高性能的保证, 利用磁盘存储来满足海量堆积能力。Kafka单机在topic数量在100+的时候,性能会下降很多,而RocketMQ能够在多个topic存在时,依然保持高性能

下面主要从存储结构、存储流程、存储优化的技术来形成文字

基于的版本是RocketMQ4.5.2

 

存储架构图

【RocketMQ源码学习】- 5. 消息存储机制

要发送的消息,会按顺序写入commitlog中,这里所有topic和queue共享一个文件

存入commitlog后,由于消息会按照topic纬度来消费,会异步构建consumeQueue(逻辑队列)和index(索引文件),consumeQueue存储消息的commitlogOffset/messageSize/tagHashCode, 方便定位commitlog中的消息实体。每个 Topic下的每个Message Queue都有一个对应的ConsumeQueue文件。索引文件(Index)提供消息检索的能力,主要在问题排查和数据统计等场景应用

消费者会从consumeQueue取到msgOffset,方便快速取出消息 

好处

CommitLog 顺序写 ,可以大大提高写人效率,提高堆积能力

虽然是随机读,但是利用操作系统的pagecache机制,可以批量地从磁盘读取,作为cache存到内存中,加速后续的读取速度

在实际情况中,大部分的 ConsumeQueue能够被全部读人内存,所以这个中间结构的操作速度很快, 可以认为是内存读取的速度

消息文件存储的结构设计

存储的文件主要分为:

commitlog: 存储消息实体

consumequeue: 按Topic和队列存储消息的offset

index: index按key、tag、时间等存储

commitlog(物理队列)

文件地址:${user.home} \store${commitlog}${fileName}

commitlog特点:

存放该broke所有topic的消息

默认1G大小

以偏移量为文件名,当一个文件写满时则创建新文件,这样的设计主要是方便根据消息的物理偏移量,快速定位到消息所在的物理文件

一个消息存储单元是不定长的

顺序写但是随机读

消息单元的存储结构

下面的表格说明了,每个消息体不是定长的,会存储消息的哪些内容,包括物理偏移量、consumeQueue的偏移量、消息体等信息

顺序 字段名 说明
1   totalSize(4Byte)   消息大小  
2   magicCode(4)   设置为daa320a7 (这个不太明白)  
3   bodyCRC(4)   当broker重启recover时会校验  
4   queueId(4)   消息对应的consumeQueueId  
5   flag(4)   rocketmq不做处理,只存储后透传  
6   queueOffset(8)   消息在consumeQueue中的偏移量  
7   physicalOffset(8)   消息在commitlog中的偏移量  
8   sysFlg(4)   事务标示,NOT_TYPE/PREPARED_TYPE/COMMIT_TYPE/ROLLBACK_TYPE  
9   bronTimestamp(8)   消息产生端(producer)的时间戳  
10   bronHost(8)   消息产生端(producer)地址(address:port)  
11   storeTimestamp(8)   消息在broker存储时间  
12   storeHostAddress(8)   消息存储到broker的地址(address:port)  
13   reconsumeTimes(4)   消息重试次数  
14   preparedTransactionOffset(8)   事务消息的物理偏移量  
15   bodyLength(4)   消息长度,最长不超过4MB  
16   body(body length Bytes)   消息体内容  
17   topicLength(1)   主题长度,最长不超过255Byte  
18   topic(topic length Bytes)   主题内容  
19   propertiesLength(2)   消息属性长度,最长不超过65535Bytes  
20   properties(properties length Bytes)   消息属性内容  

 

consumequeue文件(逻辑队列)

文件地址:${user.home}\store\consumeQueue${topic}${queueId}${fileName}

consumequeue文件特点:

按topic和queueId纬度分别存储消息commitLogOffset、size、tagHashCode

以偏移量为文件名

一个存储单元是20个字节的定长的

顺序读顺序写

每个ConsumeQueue文件大小约5.72M

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zgjgys.html