一句话先给结论
Kafka 是"分片复制"(Partition + ISR 副本),重吞吐;RabbitMQ 是"镜像队列"(Mirror Queue),重可靠。 两者架构基因不同,高可用思路完全不一样。
一、架构基因差异(决定高可用思路)
| 维度 | Kafka | RabbitMQ |
|---|---|---|
| 设计目标 | 分布式日志流(高吞吐) | 消息中间件(可靠投递) |
| 核心抽象 | Partition(分区) | Queue(队列) |
| 消息存储 | 磁盘顺序写(持久化即副本) | 内存 + 磁盘(队列即缓冲) |
| 消费模式 | 拉(Pull) | 推(Push) 为主 |
| 副本单位 | Partition 级别 | Queue 级别 |
二、Kafka 高可用:Partition + ISR 副本机制
核心机制
Topic A
├── Partition 0 (Leader) ←── 生产者只写 Leader
│ ├── Replica 1 (Follower) ←── 从 Leader 拉数据同步
│ └── Replica 2 (Follower, 当前未同步完 → 被踢出 ISR)
├── Partition 1
└── Partition 2
关键概念
- Leader / Follower:每个 Partition 有一个 Leader(处理读写),若干 Follower
- ISR(In-Sync Replicas):跟 Leader 同步的副本集合("活着的+数据追平的")
- acks 机制:生产者发送时的可靠性配置
acks=0:发完就忘(可能丢)acks=1:Leader 写完就返回(Leader 挂可能丢)acks=all:所有 ISR 同步完才返回(金融场景用这个)
故障转移流程
-
Controller (ZK 或 KRaft) 检测到 Leader 挂
-
从 ISR 列表里选新 Leader
-
通知所有生产者和消费者
-
新 Leader 接管读写
-
挂掉的 Follower 恢复后追数据,重新加入 ISR
优点
✅ 水平扩展极强 :加机器直接加 Partition
✅ 吞吐百万级/s :磁盘顺序写 + PageCache
✅ 数据零丢失(acks=all + min.insync.replicas=2)
✅ 天然支持回溯消费 :消息持久化在磁盘
✅ Leader 选举快:毫秒级(基于 ZK/KRaft)
缺点
⚠️ 架构复杂 :ZK 或 KRaft + 多 Controller + Partition 调度
⚠️ 脑裂问题 :网络分区时可能选双 Leader(用 unclean.leader.election.enable=false 解决)
⚠️ 扩容慢:Partition 数只能加不能减(要预先规划)
三、RabbitMQ 高可用:镜像队列(Mirror Queue)机制
核心机制
Producer → Exchange
↓
Queue (主节点)
├── Mirror Node 1 ←── 实时同步
├── Mirror Node 2 ←── 实时同步
└── Mirror Node 3 ←── 实时同步
关键概念
- Queue 默认存在一个节点上(性能考虑)
- Mirror Queue :把队列复制到多个节点(可选,按 policy 配)
- 同步方式:
- 普通镜像:异步复制(可能丢)
- Quorum Queue(新,3.10+) :基于 Raft 强一致(推荐)
故障转移流程
-
主节点挂
-
最老的 Mirror 自动晋升为主
-
客户端通过连接重试机制重新连接
-
消息继续流转
优点
✅ 部署简单 :单机也能跑,集群开镜像就好
✅ 路由灵活 :Exchange 类型丰富(direct/topic/fanout/headers)
✅ 管理界面友好 :Web UI 直接看队列、消息、消费者
✅ 低延迟 :消息入队即返回
✅ AMQP 协议标准:跨语言支持好
缺点
⚠️ 吞吐受限 :单队列在万级/s(Kafka 是百万级)
⚠️ 镜像队列性能差 :所有节点都要写一份(Quorum Queue 解决了一部分 )
⚠️ 扩容难 :队列不能跨节点分片(这是和 Kafka 最大的架构差异)
⚠️ 脑裂问题更严重 :网络分区时两边都能收消息(要靠federation/shovel)
四、核心差异对比表(面试必背)
| 维度 | Kafka | RabbitMQ |
|---|---|---|
| 高可用单位 | Partition 多副本 | Queue 镜像 |
| 副本数量 | 可配置(通常 3) | 可配置(通常 2-3) |
| 故障切换 | Controller 自动选 Leader(毫秒) | 客户端重连 + Mirror 晋升(秒级) |
| 数据一致性 | 最终一致(acks=all 才强一致) | 镜像队列 = 最终一致 Quorum Queue = 强一致 |
| 脑裂处理 | unclean.leader.election=false 防止 |
镜像队列会双写 Quorum Queue 用 Raft 解决 |
| 消息可靠性 | 配置到位可零丢失 | 配置到位可零丢失 |
| 性能(单集群) | 百万/s | 万级/s |
| 延迟 | ms 级(批量发送) | μs 级(单条确认) |
| 回溯消费 | ✅ 天然支持(offset 重置) | ❌ 不支持(消费即删除,除非手动持久化) |
| 运维复杂度 | 高(ZK/KRaft + 调优参数多) | 低(Web UI 直接看) |
| 典型场景 | 日志收集、流计算、事件溯源、削峰 | 订单、支付、RPC 异步化、任务调度 |
五、面试话术(30 秒杀手锏)
"两者高可用思路完全不同------
Kafka 用 Partition + ISR 副本:每个分区有 Leader 和 Follower,靠 ZK/KRaft 选主,故障切换毫秒级;acks=all + min.insync.replicas=2 可以做到零丢失;强项是水平扩展和回溯消费。
RabbitMQ 用镜像队列(Mirror Queue):把队列复制到多个节点,主挂 Mirror 晋升,秒级切换;新版 Quorum Queue 用 Raft 协议解决了脑裂问题;强项是低延迟和灵活路由。
架构基因差异 :Kafka 是分布式日志(吞吐优先),RabbitMQ 是消息中间件(投递可靠)。金融场景两者都能用------Kafka 走配置 +acks=all 保零丢,RabbitMQ 用 Quorum Queue 保强一致。"
六、实战选型(金融项目)
| 场景 | 推荐 | 原因 |
|---|---|---|
| 日志/审计/事件流 | Kafka | 高吞吐 + 回溯消费(监管要求保留 5 年) |
| 订单/支付/交易 | RabbitMQ Quorum Queue | 强一致 + 低延迟(不能丢单) |
| 削峰填谷(如秒杀) | Kafka | 大流量场景 + 消费者弹性扩容 |
| 延迟任务(30min 后执行) | RabbitMQ + 死信队列 | 天然支持 TTL + DLX |
| 分布式事务最终一致 | Kafka | 事务消息 + 消费位点严格控制 |
| RPC 异步化 | RabbitMQ | 简单 + 灵活路由 |