面试官:你了解RocketMQ是如何存储消息的吗?
我:额,,,你等下,我看下这篇文字, (逃
由于这部分内容优点多,所以请哥哥姐姐们自备茶水,欢迎留言!
RocketMQ存储设计是高可用和高性能的保证, 利用磁盘存储来满足海量堆积能力。Kafka单机在topic数量在100+的时候,性能会下降很多,而RocketMQ能够在多个topic存在时,依然保持高性能
下面主要从存储结构、存储流程、存储优化的技术来形成文字
基于的版本是RocketMQ4.5.2
存储架构图
要发送的消息,会按顺序写入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