消息存储整体架构
我们先把RocketMQ github上的消息存储图荡下来瞅瞅;
消息存储主要体现在三个文件中:CommitLog
(真正存储消息体的地方)、ConsumeQueue
(某个Topic下某个Queue的消息索引信息)、IndexFile
(通过key或时间区间来查询消息的索引文件)。
简版:
细版:
producer发送消息后,消息先保存到commitLog,再异步建立该条消息对应的topic + queue对应的ConsumerQueue索引。
1、CommitLog
CommitLog是消息本身、元数据的存储主体:
- 其存储Producer端写入的消息主体内容(包括:消息体、属性、UID等);
- 因每条消息长度不一致,所以每个commitLog的记录也不是定长的。
- 单个CommitLog文件大小默认最大1G, 文件名长度20位,左边补零,剩余为CommitLog中消息的起始偏移量;比如:
- 00000000000000000000代表了第一个文件,消息起始偏移量为0;
- 由于1G=1073741824B;所以当第一个文件写满了之后,第二个文件名为00000000001073741824,消息起始偏移量为1073741824;
- CommitLog文件名以此类推。消息顺序写入日志文件,当文件满了或者不足以容纳最后一条消息之后,消息写入下一个文件。
以我的服务器为例,CommitLog日志文件存储在/root/store/commitlog文件夹中;而我的commitLog文件只有一个,所以它的文件名为:00000000000000000000。
2、ConsumeQueue
ConsumeQueue–逻辑消息消费队列,主要作用是提高消息消费的性能。
- 由于RocketMQ是基于主题topic的订阅模式,且消息消费也是针对主题进行的;所以如果要遍历commitlog文件,再根据topic检索消息是非常低效的。
- 由于ConsumeQueue的存在,Consumer可以根据ConsumeQueue来查找待消费的消息。
- ConsumeQueue作为消费消息的索引,保存了指定Topic下的指定队列消息在CommitLog中的起始物理偏移量offset,消息大小size和消息Tag的HashCode值。
- ConsumeQueue文件可以看做是基于topic的CommitLog索引文件,所以ConsumeQueue文件夹的组织方式如下:
topic/queue/file
三层组织结构;具体存储路径为:$HOME/store/consumequeue/{topic}/{queueId}/{fileName}
。- 和CommitLog不同,ConsumeQueue文件采取定长设计,每一个条目共20个字节(8字节的commitlog物理偏移量、4字节的消息长度、8字节tag hashcode);
注意第三部分TaghashCode是服务端过滤消息的重要依据。
- 单个文件最多由30W个条目组成,我们可以随机访问每一个条目,每个ConsumeQueue文件最大约5.72M。
ConsumeQueue文件存储在/root/store/consumequeue
文件夹中;由于ConsumeQueue是以Topic为维度进行划分的,所以文件夹会多一级topicName,即/root/store/consumequeue/saint-study-topic
。RocketMQ默认会为每个Topic创建4个ConsumeQueue,即下图的0、1、2、3文件夹。
3、IndexFile
IndexFile(索引文件)提供了一种可以通过key或时间区间来查询消息的方法。
- Index文件的存储位置是:
$HOME\store\index\${fileName}
,文件名fileName是以创建时的时间戳命名的; - 固定的单个IndexFile文件最大约为400M,一个IndexFile可以保存 2000W个索引;
- IndexFile的底层存储设计为在文件系统中实现HashMap结构,所以rocketmq的索引文件其底层实现为hash索引。
总结
RocketMQ采用的是混合型的存储结构。
Broker单个实例下所有的队列共用一个日志数据文件(CommitLog)来存储;即多个Topic的消息实体内容都存储于一个CommitLog中。
针对Producer和Consumer采用了数据和索引部分相分离的存储结构:
- Producer发送消息至Broker端后,Broker端使用同步或者异步的方式对消息刷盘持久化,保存至CommitLog中。
- Broker端启动一个后台服务线程—ReputMessageService不停地分发请求并异步构建ConsumeQueue(逻辑消费队列)和IndexFile(索引文件)数据。