Topic 、Queue、 CommitLog、ConsumeQueue 和 IndexFile 的关系

379 阅读3分钟

在 RocketMQ 中,Topic 和 Queue 的关系以及它们与 CommitLog、ConsumeQueue 和 IndexFile 的关系如下: output.png

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:

  1. TopicA

    • 对应 4 个 Queue(Queue0, Queue1, Queue2, Queue3)。
  2. CommitLog

    • 全局共享的日志文件,所有 Topic 和 Queue 的消息都写入到同一个 CommitLog 文件中。
    • 随着消息的不断写入,CommitLog 文件会不断创建新的文件(默认每个文件 1GB)。
  3. ConsumeQueue

    • TopicA 的每个 Queue 都有一个对应的 ConsumeQueue 文件。
    • TopicA 对应 4 个 Queue,因此会有 4 个 ConsumeQueue 文件(ConsumeQueue0, ConsumeQueue1, ConsumeQueue2, ConsumeQueue3)。
  4. IndexFile

    • 如果 TopicA 的消息带有 key,那么会在 IndexFile 中创建索引。
    • IndexFile 文件数量根据消息 key 的数量和哈希冲突情况决定,通常按需创建。

示例总结

  • TopicA 对应 4 个 Queue,每个 Queue 对应一个 ConsumeQueue 文件,共 4 个 ConsumeQueue 文件。
  • CommitLog 文件是全局共享的,不同的 Topic 和 Queue 共用同一个 CommitLog 文件集合。
  • IndexFile 文件按需创建,具体数量取决于消息 key 的数量和哈希冲突情况。

通过以上设计,RocketMQ 能够高效地管理和存储消息,实现快速的消息查找和消费。