在 RocketMQ 中,Topic 和 Queue 的关系以及它们与 CommitLog、ConsumeQueue 和 IndexFile 的关系如下:
RocketMQ 磁盘上目录结构
/var/rocketmq/store
├── commitlog
├── config
│ ├── consumerOffset.json
│ ├── delayOffset.json
│ ├── subscriptionGroup.json
│ └── topics.json
├── consumequeue
│ ├── {topic}
│ │ ├── {queueId}
│ │ │ ├── 00000000000000000000
│ │ │ ├── 00000000000000000001
│ │ │ └── ...
│ │ ├── ...
├── index
│ ├── 20210602101245678
│ ├── 20210602112356789
│ └── ...
└── checkpoint
比如
/var/rocketmq/store
├── commitlog # 存储所有消息内容
│ ├── 00000000000000000000
│ ├── 00000000001073741824
│ └── ...
├── config # 存储配置文件
│ ├── consumerOffset.json # 存储消费者的消费进度
│ ├── delayOffset.json # 存储延迟消息进度
│ ├── subscriptionGroup.json # 存储订阅组信息
│ └── topics.json # 存储主题配置信息
├── consumequeue # 存储每个主题的消息队列索引
│ ├── TopicA
│ │ ├── 0
│ │ │ ├── 00000000000000000000
│ │ │ ├── 00000000000000000001
│ │ │ └── ...
│ │ ├── 1
│ │ ├── 00000000000000000000
│ │ ├── 00000000000000000001
│ │ └── ...
│ └── TopicB
│ ├── 0
│ │ ├── 00000000000000000000
│ │ ├── 00000000000000000001
│ │ └── ...
│ ├── 1
│ ├── 00000000000000000000
│ ├── 00000000000000000001
│ └── ...
├── index # 存储消息索引文件
│ ├── 20210602101245678
│ ├── 20210602112356789
│ └── ...
└── checkpoint # 存储刷盘进度
├── checkpoint
Topic 和 Queue 的关系
- Topic 和 Queue:一个 Topic 可以有多个 Queue。默认情况下,一个 Topic 会有
4 个 Queue,这个数量是可以配置的。 - Queue 的配置:创建 Topic 时可以指定 Queue 的数量,实际应用中可以根据需求调整这个数量。
CommitLog
- 全局共享:
所有 Topic 和 Queue 的消息数据都存储在同一个 CommitLog 文件中。CommitLog 是全局共享的,不同的 Topic 和 Queue 只是记录了它们的消息在 CommitLog 中的位置。 - 文件切分:CommitLog 文件默认大小为 1GB,文件写满后会创建新的文件进行存储。
ConsumeQueue
- 每个 Queue 对应一个 ConsumeQueue:
每个 Queue 都有一个对应的 ConsumeQueue 文件,用于存储该 Queue 中消息在 CommitLog 中的位置索引。 - 文件结构:每个 ConsumeQueue 文件的记录大小是固定的(20 字节),包含消息在 CommitLog 中的物理偏移量、消息大小和 Tag hashcode。
IndexFile
- 按需创建:IndexFile 是基于消息的 key 创建的索引文件。
如果消息带有 key,会在 IndexFile 中记录消息的索引。 - 文件结构:IndexFile 使用哈希表存储索引,每个哈希桶记录消息的 CommitLog 偏移量和时间戳。
具体关系和数量示例
假设我们有一个 TopicA,默认配置了 4 个 Queue:
-
TopicA:
- 对应 4 个 Queue(Queue0, Queue1, Queue2, Queue3)。
-
CommitLog:
- 全局共享的日志文件,所有 Topic 和 Queue 的消息都写入到同一个 CommitLog 文件中。
- 随着消息的不断写入,CommitLog 文件会不断创建新的文件(默认每个文件 1GB)。
-
ConsumeQueue:
- TopicA 的每个 Queue 都有一个对应的 ConsumeQueue 文件。
- TopicA 对应 4 个 Queue,因此会有 4 个 ConsumeQueue 文件(ConsumeQueue0, ConsumeQueue1, ConsumeQueue2, ConsumeQueue3)。
-
IndexFile:
- 如果 TopicA 的消息带有 key,那么会在 IndexFile 中创建索引。
- IndexFile 文件数量根据消息 key 的数量和哈希冲突情况决定,通常按需创建。
示例总结
- TopicA 对应 4 个 Queue,每个 Queue 对应一个 ConsumeQueue 文件,共 4 个 ConsumeQueue 文件。
- CommitLog 文件是全局共享的,不同的 Topic 和 Queue 共用同一个 CommitLog 文件集合。
- IndexFile 文件按需创建,具体数量取决于消息 key 的数量和哈希冲突情况。
通过以上设计,RocketMQ 能够高效地管理和存储消息,实现快速的消息查找和消费。