一、RocketMQ的存储设计
1.1 Domain Model
1.1.1 Message
Message是RocketMQ消息引擎中的主体。messageId是全局唯一的。MessageKey是业务系统(生产者)生成的,所以如果要结合业务,可以使用MessageKey作为业务系统的唯一索引。
1.1.2 Topic
subTopics==Message Queue,其实在内存逻辑中,subTopics是对Topics的一个拓展,尤其是在MQTT这种协议下,在Topic底下会有很多subTopics。
1.1.3 Queue
Queue是消息物理管理单位,比如在RocketMQ的控制台中,就可以看到每一个queue中的情况(比如消息的堆积情况、消息的TPS、QPS)
1.1.4 Offset
对于每一个Queue来说都有Offset,这个是消费位点。
1.1.5 Group
业务场景中,如果有一堆发送者,一堆消费者,所以这里使用Group的概念进行管理。
1.1.6 对应关系
Message与 Topic是多对一的关系,一个Topic可以有多个Message.
Topic到Queue是一对多的关系,这个也是方便横向拓展,也就是消费的时候,这里可以有很多很多的Queue.
一个Queue只有一个消费位点(Offset),所以Topic和Offset也是一对多的关系Topic和Group也是多对多的关系。
1.1.7 消费并发度
从上面模型可以看出,要解决消费并发,就是要利用Queue,一个Topic可以分出更多的queue,每一个queue可以存放在不同的硬件上来提高并发。
二、消息存储结构
RocketMQ因为有高可靠性的要求(宕机不丢失数据),所以数据要进行持久化存储。所以RocketMQ 采用文件进行存储。
2.1 存储文件
- commitlog:消息存储目录;
- config:运行期间的一些配置信息;
- consumequeue:消息消费队列存储目录;
- index:消息索引文件存储目录;
- checkpoint:文件检查点,存储commitlog最后一次刷盘时间,consumequeue最后一次刷盘时间,index索引文件最后一次 刷盘时间。
2.2 消息存储结构
RocketMQ消息的存储是由ConsumeQueue和CommitLog配合完成 的,消息真正的物理存储文件是CommitLog,ConsumeQueue是消息的逻辑队列,类似数据库的索引文件,存储的是指向物理存储的地址。每 个Topic下的每个Message Queue都有一个对应的ConsumeQueue文件。
- commitlog:存储消息的元数据;
- comsumequeue:存在消息在commitlog的索引;
- indexfile:为了消息查询提供了一种通过key或时间区间来查询消息的方法,这种通过IndexFile来查找消息的方法不影响发送与消费消息的主流程;
2.2.1 commitlog
CommitLog 以物理文件的方式存放,每台 Broker 上的 CommitLog 被本机器所有 ConsumeQueue 共享,文件地址:$ {user.home} \store\$ { commitlog} \ $ { fileName}。在CommitLog 中,一个消息的存储长度是不固定的, RocketMQ采取一些机制,尽量向CommitLog 中顺序写 ,但是随机读。commitlog 文件默认大小为lG ,可通过在 broker 置文件中设置 mappedFileSizeCommitL