前言
之前有写过关于kafka的存储结构的文章。RocketMQ大部分是借鉴了Kafka的设计原理,但是副本集群机制和存储结构有些差异。看完本篇文章可以看看这篇。消息中间件之kafka
RocketMQ 的消息存储机制是其高吞吐、高可用和高可靠性的关键。以下将介绍 RocketMQ 消息存储的核心机制
1. 存储架构
RocketMQ 的消息存储主要由以下部分组成:
- CommitLog: 所有消息都顺序写入 CommitLog 文件,保证高吞吐。
- ConsumeQueue: 每个消息队列(Topic+Queue)对应一个 ConsumeQueue,存储消息在 CommitLog 中的偏移量,方便快速检索。
- IndexFile: 提供基于消息 Key 或时间范围的查询功能。
2. CommitLog
- 顺序写入: 所有消息按顺序追加到 CommitLog 文件,提升写入性能。
- 文件大小固定: 每个 CommitLog 文件默认 1GB,写满后创建新文件。
- 异步刷盘: 支持同步和异步刷盘,异步刷盘通过批量写入提升性能,同步刷盘则保证数据不丢失。
3. ConsumeQueue
- 消息索引: 存储消息在 CommitLog 中的物理偏移量、大小和 Tag 哈希值,方便快速定位消息。
- 文件分段: 每个 ConsumeQueue 文件默认存储 30万条索引,文件大小固定。
- 异步构建: ConsumeQueue 通过异步方式从 CommitLog 构建,不影响主写入流程。
4. IndexFile
-
索引服务: 提供基于消息 Key 或时间范围的查询,文件大小固定(默认 400MB)。
-
哈希索引: 通过哈希索引快速定位消息位置。
-
5. 消息存储流程
- 消息写入: 生产者发送消息,Broker 将其顺序写入 CommitLog。
- 构建索引: 异步构建 ConsumeQueue 和 IndexFile。
- 消息读取: 消费者通过 ConsumeQueue 找到消息在 CommitLog 中的位置,读取消息。
6. 刷盘机制
- 同步刷盘: 消息写入 CommitLog 后立即刷盘,保证数据不丢失,但性能较低。
- 异步刷盘: 消息写入 CommitLog 后先存入 PageCache,由操作系统异步刷盘,性能较高,但可能丢失部分数据。
7. 文件清理
- 过期清理: 定期清理过期消息(默认 72 小时)。
- 文件删除: 根据磁盘使用情况删除旧的 CommitLog 文件。
8. 高可用性
- 主从复制: Broker 支持主从架构,主节点将消息同步到从节点,主节点故障时从节点可继续提供服务。
- 数据冗余: 通过多副本机制保证数据不丢失。
9. 性能优化
- 零拷贝: 通过
mmap
和sendfile
技术减少数据拷贝,提升性能。 - 批量写入: 支持批量消息写入,减少 IO 操作。
总结
RocketMQ 通过 CommitLog 顺序写入、ConsumeQueue 索引、IndexFile 查询等机制实现高效的消息存储和检索,并通过同步/异步刷盘、主从复制等技术保证高可用性和可靠性。