RocketMQ消息是如何存储的
RocketMQ的消息存储是一个复杂而高效的过程,设计上充分考虑了性能和扩展性,
消息存储的主要组件包括CommitLog文件、消费队列文件(ConsumerQueue)、以及索引文件(IndexFile)
一、CommitLog文件
CommitLog是Rocketmq的核心存储文件,负责保持消息的完整内容
- 
顺序写入:所有的消息都是顺序写入CommitLog文件,这种方式减少了磁盘寻道时间,提高了写入性能 
- 
文件滚动:CommitLog按照固定大小(比如1GB)进行分片。当一个文件写满后,会创建一个新的文件 
- 
存储所有数据:包括消息体、主题、队列ID等 
- 
刷盘策略: - 
同步刷盘(SYNC_FLUSH):消息写入磁盘后才返回 ACK,可靠性高但性能较低 
- 
异步刷盘(ASYNC_FLUSH):消息写入 PageCache 后立即返回 ACK,由后台线程定期刷盘(默认策略) 
 
- 
二、ConsumerQueue
ConsumerQueue是针对消息的逻辑图,指在加快消费者对消息的快速定位
- 
异步分发:后台线程 ReputMessageService 定时从 CommitLog 提取消息,按 Topic 和 Queue 分发到对应的 ConsumeQueue 
- 
索引结构:每个 ConsumeQueue 条目固定 20 字节,包含: | CommitLog Offset (8B) | Size (4B) | Message Tag Hash (8B) | 通过 CommitLog Offset 和 Size 可快速定位消息在 CommitLog 中的位置
三、可选,构建 IndexFile
- 哈希索引:根据消息的 Key 或 Tag 构建哈希索引(IndexFile),支持按消息 Key 查询(如事务消息回查)
四、消息读取流程(消费过程)
1、消费者拉取消息:
- 
根据 Topic 和 Queue ID 找到对应的 ConsumeQueue 
- 
从 ConsumeQueue 中读取条目,获取消息在 CommitLog 的物理偏移量(Offset)和 Size 
2、定位 CommitLog:
- 根据 CommitLog Offset 和 Size,直接从 CommitLog 文件读取完整消息内容
五、存储优化机制
1、页缓存(PageCache)加速
- 
RocketMQ 利用 Linux 的 PageCache 机制,优先读写内存缓存,大幅减少磁盘 IO 
- 
建议:Broker 机器预留 50% 内存供 PageCache 使用 
2、文件预分配
- CommitLog 和 ConsumeQueue 文件预先分配固定大小(如 1GB),避免动态扩容带来的性能抖动
3、过期文件清理
- 默认保留 72 小时消息,可通过配置调整:

后台线程定期删除过期文件,释放磁盘空间
六、高可用设计
1、主从同步(Replication)
- 
同步复制(SYNC_MASTER):Master 需等待 Slave 存储成功后才返回 ACK,确保数据不丢失 
- 
异步复制(ASYNC_MASTER):Master 写入后立即返回 ACK,性能更高但可能丢消息 
2、故障恢复
- 
Broker 宕机:Slave 自动切换为 Master(需配合 DLedger 或 RAFT 协议) 
- 
磁盘损坏:从 Slave 节点恢复数据 
七、存储配置建议

八、可视化存储状态
通过命令查看存储状态:

九、总结
- 
CommitLog:消息全集,顺序写入,保证高吞吐。 
- 
ConsumeQueue:逻辑队列索引,内存映射加速检索。 
- 
设计优势: - 
顺序写盘 + 异步构建索引 → 高性能。 
- 
主从同步 + 刷盘策略 → 高可靠。 
 
- 
- 
适用场景: - 顺序写、随机读的日志型存储模型,适合消息中间件场景。
 
 
                    
                     
                    
                 
                    
                
 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号