RocketMQ架构#
一句话答案#
RocketMQ 四大组件:NameServer(无状态注册中心)、Broker(消息存储与转发)、Producer(发送方)、Consumer(消费方),Broker 主从部署,NameServer 去中心化。
核心要点
四大组件#
Producer → NameServer(查 Broker 地址)→ Broker(存储消息)→ Consumerplaintext| 组件 | 职责 | 特点 |
|---|---|---|
| NameServer | 路由注册与发现 | 无状态,去中心化,各节点独立 |
| Broker | 消息存储、转发、过滤 | 主从部署,主写从读 |
| Producer | 消息发送 | 从 NameServer 获取路由,直连 Broker |
| Consumer | 消息消费 | 支持 Push / Pull 两种模式 |
NameServer vs ZooKeeper#
| 维度 | NameServer | ZooKeeper |
|---|---|---|
| 一致性 | 最终一致(各节点独立) | 强一致(ZAB 协议) |
| 复杂度 | 极简,无选举 | 复杂,需要选举 |
| 依赖 | 无外部依赖 | 需要独立集群 |
RocketMQ 选择 NameServer 因为消息路由不需要强一致性,最终一致够用。
Broker 存储模型#
CommitLog: 所有消息顺序追加写(一个大文件)
→ 高性能顺序写
ConsumeQueue: 每个 Topic 的每个 Queue 一个索引文件
→ 记录消息在 CommitLog 中的偏移量
→ 消费时先查 ConsumeQueue 再读 CommitLog
IndexFile: 可选的消息索引(按 Key 查询消息)plaintext设计优势: 所有 Topic 共用一个 CommitLog 顺序写 → 写性能不随 Topic 数增加而下降(对比 Kafka 每个 Partition 独立文件)。
Kafka vs RocketMQ#
| 维度 | Kafka | RocketMQ |
|---|---|---|
| 定位 | 高吞吐日志/流处理 | 业务消息(事务/延迟/顺序) |
| 存储 | 每个 Partition 独立文件 | 所有消息共用 CommitLog |
| 事务消息 | 面向流处理 | 半消息 + 回查(业务事务) |
| 延迟消息 | 不原生支持 | 原生支持(18 个级别) |
| 消息回溯 | 按 offset | 按时间 |
面试回答(2分钟版)
RocketMQ的架构由四大组件组成:NameServer是无状态的路由注册中心,各节点独立互不通信,Broker启动时向所有NameServer注册;Broker负责消息的存储和转发,支持主从部署实现高可用;Producer从NameServer获取路由信息后直连Broker发送消息;Consumer支持Push和Pull两种消费模式。RocketMQ选择自研NameServer而不用ZooKeeper,是因为消息路由不需要强一致性,最终一致就够用,而NameServer更简单无选举无外部依赖。存储模型是RocketMQ的核心亮点:所有Topic的消息都顺序追加写入同一个CommitLog文件,保证了极高的写入性能;每个Topic的每个Queue有一个ConsumeQueue索引文件记录消息在CommitLog中的偏移量,消费时先查ConsumeQueue再读CommitLog。这个设计和Kafka的区别在于Kafka每个Partition独立文件,Topic多了写性能会下降,而RocketMQ共用CommitLog写性能不受Topic数量影响。功能上RocketMQ更偏向业务消息,原生支持事务消息和延迟消息。
追问与易错
追问方向:
- “为什么不用 ZooKeeper?”→ 消息路由不需要强一致,NameServer 更简单
- “CommitLog 和 ConsumeQueue 的关系?”→ CommitLog 存消息体,ConsumeQueue 存索引
易错点:
- ❌ “NameServer 之间会同步数据”——各节点独立,Broker 向所有 NameServer 注册
- ❌ “RocketMQ 和 Kafka 一样每个 Topic 独立存储”——RocketMQ 共用 CommitLog