主题
附录 B:Kafka vs 其它消息中间件横向对比
工具书用法:遇到「到底该选谁 / 这俩到底差在哪」的问题,按目录跳着查即可。
对比对象(统一选截至 2024 ~ 2025 年的主流版本):
- Apache Kafka 3.8 / 4.0(KRaft 模式)
- RabbitMQ 3.13(Classic + Quorum Queue + Streams 都讲)
- Apache RocketMQ 5.x
- Apache Pulsar 3.x
- Redis Stream(Redis 7+ XADD / XREADGROUP 系列命令)
- NATS JetStream 2.10+
目录
- 一句话定位 & 选型矩阵
- 存储模型对比
- 消费模型对比(推 vs 拉、ACK、Offset)
- 路由能力对比
- 顺序保证粒度
- 事务 / EOS 实现路径
- 延迟消息支持
- 死信 / 重试机制
- 架构(计算与存储是否分离)
- 元数据管理
- 延迟与吞吐基准(典型量级)
- 生态与多语言客户端
- 运维复杂度
- 典型场景适配矩阵
- 详细对比章节
- 「场景 → 推荐 MQ」决策树
1. 一句话定位 & 选型矩阵
| MQ | 一句话定位 | 最强场景 | 最弱场景 |
|---|---|---|---|
| Kafka | 分布式提交日志 + 流处理平台 | 高吞吐 / 可重放 / 数据总线 / 大数据流 | 低延迟 RPC、复杂路由、海量小 Topic |
| RabbitMQ | 「智能交换机」+ 多协议消息代理(AMQP/STOMP/MQTT) | 业务异步解耦、复杂路由、需要 RPC 风格 | 超高吞吐(GB/s)、长期可重放 |
| RocketMQ | 阿里电商场景磨出来的「业务消息」系统 | 顺序消息、事务消息、海量 Topic、延时消息 | 多语言生态(主要 Java) |
| Pulsar | 计算 / 存储分离的下一代日志平台 | 多租户、跨地域、需要弹性扩缩 Broker | 运维复杂、社区中文资料少 |
| Redis Stream | Redis 内置的「轻量流」 | 已经在用 Redis、消息量不大、只想加点队列能力 | 持久化要求高、跨数据中心 |
| NATS JetStream | 云原生「轻量持久化流」(NATS 协议) | K8s / IoT / 边缘、超低延迟 + 持久化 | 巨大历史数据回放、复杂事务 |
2. 存储模型对比
| 维度 | Kafka | RabbitMQ Classic | RabbitMQ Quorum / Stream | RocketMQ | Pulsar | Redis Stream | NATS JetStream |
|---|---|---|---|---|---|---|---|
| 核心结构 | 顺序日志 segment + 稀疏索引 | 内存队列 + lazy queue 持久化 | Quorum: Raft 日志;Stream: 类 Kafka segment | CommitLog + ConsumeQueue + IndexFile | BookKeeper Ledger(多副本日志) | radix tree + AOF / RDB | File-based stream + 内存索引 |
| 写入模式 | 顺序追加写 | 出 / 入队随机 | Quorum: 顺序追加;Stream: 顺序追加 | 顺序追加写(CommitLog 单文件) | 顺序追加写(BookKeeper Bookie) | 内存写 + AOF 异步刷盘 | 顺序追加写 |
| 读路径 | PageCache + 零拷贝 sendfile | 内存优先 / 磁盘 fallback | Stream: 类 Kafka,PageCache + 零拷贝 | PageCache(与 Kafka 同思路) | BookKeeper 客户端按 Ledger 读 | 内存直接读 | 内存索引 + 文件读 |
| 多副本 | Topic 级副本 + ISR 选举 | 镜像队列(已退役)/ Quorum Raft | Stream 自带副本 | DLedger(Raft)或 主从异步 | BookKeeper 多 Bookie 写入(Quorum) | Sentinel / Cluster 主从 | RAFT-based replication |
| 持久化粒度 | 分区 → segment → record | 队列 → 消息 | 同 Kafka | Topic → Queue → CommitLog 偏移 | Topic → Partition → Ledger → Entry | Stream → Entry | Stream → Block |
| 删除 / 保留 | 时间 / 字节 / Compact 三种 | 消费 ACK 即删;可设 TTL | Stream: 时间 / 字节 / 大小 | 时间 + 容量 | 时间 / 大小 + 分层(Tiered) | MAXLEN / MINID / 时间 | 时间 / 字节 / 数量 |
| 冷热分层 | Tiered Storage 3.6+(KIP-405) | 无 | 无 | 部分支持(tieredStoreEnable) | 原生支持(Tiered Storage 经典优势) | 无 | 无 |
| 典型单 broker 容量 | TB ~ PB(限于磁盘) | GB(队列长了会撑爆内存) | TB(Stream) | TB | 由 BookKeeper 横向扩 | 几 GB(受内存制约) | TB |
速记口诀:
Kafka / RocketMQ / Pulsar / RabbitMQ Stream:本质都是顺序追加日志,吞吐量级一致。 RabbitMQ Classic:队列中间件,本质内存数据结构 + 持久化兜底,吞吐 1~2 个数量级低,但路由灵活。 Redis Stream / NATS JetStream:内存优先 + 文件兜底,吞吐随内存大小。
3. 消费模型对比
| 维度 | Kafka | RabbitMQ | RocketMQ | Pulsar | Redis Stream | NATS JetStream |
|---|---|---|---|---|---|---|
| 拉 vs 推 | 拉(Pull) | 推(Push, basic.consume) | 拉为主,可推(DefaultMQPushConsumer 内部其实也是长轮询拉) | 推 + 拉两种 API(Subscribe / Reader) | XREAD/XREADGROUP 拉 | 拉(Pull Consumer)+ 推(Push Consumer) |
| 消费位点 | Consumer Group offset → __consumer_offsets | 不存位点,Broker 收到 ack 即删消息 | Consumer 内部记录 + Broker 持久化 offset | Subscription → cursor,Broker 持久化 | Consumer Group last-id | Consumer state(Broker 持久化) |
| ACK 模型 | 提交 offset = 隐式 ACK,与消息不绑定 | 显式 basic.ack/nack 单条 / 批量 | 显式 ACK,类似 RabbitMQ | 显式 acknowledge(messageId) 单条 / 累积 | XACK 单条 | 显式 ACK 单条 / 批量 |
| 可重放 | 天然支持(offset 任意 seek) | 不支持(消费即删;除非用 Stream 插件) | 支持(reset offset) | 支持(reset cursor) | 支持(XREAD with id) | 支持(DeliverPolicy = ByStartSequence/Time) |
| 消息留存与消费解耦 | 完全解耦(消费者 lag 不影响保留) | 耦合(队列长度 = 未消费消息数) | 解耦(CommitLog 按时间清) | 解耦(Ledger 按时间清) | 半解耦(MAXLEN 截断) | 解耦 |
| 消费组语义 | Consumer Group:组内分区独占;组间广播 | 队列竞争消费 + Topic 多 binding 实现广播 | Cluster(独占)/ Broadcast 两种 | Subscription:Exclusive / Shared / Failover / Key_Shared | Consumer Group:组内 PEL 独占 | DeliverGroup:组内独占 |
| 顺序保证 | 分区内严格顺序 | 单队列顺序 | 单 MessageQueue 内顺序,全局顺序需单 Queue | Subscription Type=Key_Shared 时 Key 内顺序 | 单 stream 顺序 | 单 subject 内顺序 |
| 死信 / 重试可配 | 客户端自实现,或 Streams DLQ | 内建 DLX(Dead Letter Exchange) | 内建重试队列 + DLQ(%RETRY%/%DLQ%) | 内建 retry topic + DLQ | 自实现 / RedisGears | 内建 MaxDeliver + DLQ subject |
速记:
Kafka 是「日志读取者」:消费 = 移动读指针,不消费数据本身。 RabbitMQ 是「队列搬运工」:消费 = 把消息从队列里搬出来。
4. 路由能力对比
| 维度 | Kafka | RabbitMQ | RocketMQ | Pulsar | Redis Stream | NATS JetStream |
|---|---|---|---|---|---|---|
| 路由模型 | Key Hash → Partition(仅此一种) | Exchange + Binding(Direct / Fanout / Topic / Headers / x-consistent-hash 等) | Topic + Tag + SQL92 过滤 | Topic + 可选 Function 过滤 | 仅按 Stream Key | Subject 通配符(a.b.*、a.b.>)+ Filter Subject |
| 服务端过滤 | ❌ 无(消费端自己过滤) | ✅ Routing Key / Headers 服务端匹配 | ✅ Tag + SQL 服务端过滤 | ✅ Function 过滤 | ❌ | ✅ Subject 通配符服务端匹配 |
| 多目的地(Fan-out) | 多 Consumer Group 各读一份 | Fanout Exchange 一进多出 | Topic 多组消费 | Subscription 多个 | XADD 后多 group 读 | 多个 Stream / Consumer 订同一 subject |
| 优先级队列 | ❌ 不支持 | ✅ x-max-priority | ❌ | ❌(用多 Topic 模拟) | ❌ | ❌ |
速记:
想要「业务 A 走风控、业务 B 走通知、业务 C 走数仓」这种复杂路由——RabbitMQ / NATS / RocketMQ Tag 都比 Kafka 直观。 Kafka 的解法是:多 Topic + 多 Consumer Group,把路由放到客户端。
5. 顺序保证粒度
| MQ | 顺序粒度 | 全局有序代价 |
|---|---|---|
| Kafka | 单分区(partition)内严格有序 | 全局有序 = 单分区,吞吐被 1 个分区上限锁死 |
| RabbitMQ Classic | 单队列内有序 | 全局 = 单队列,且要 single active consumer |
| RabbitMQ Quorum / Stream | 单队列内严格有序 | 同上 |
| RocketMQ | 单 MessageQueue 内有序;提供「顺序消息」类型保证 | 全局 = 单 MessageQueue |
| Pulsar | Subscription Type=Key_Shared 时同 Key 顺序;Exclusive 全 Topic 顺序 | 全局 = 单分区 + Exclusive |
| Redis Stream | 单 stream 内 entry-id 单调递增 | 全局 = 单 stream |
| NATS JetStream | 单 subject + 单 consumer 顺序 | 全局 = 单 subject |
📌 公理:所有日志型 MQ「全局有序」都意味着牺牲并行度,只有单分区 / 单队列 / 单 subject 能提供。所以实战中尽量用「业务 Key 维度有序」(Kafka 用 Key 落同分区即可),不要追求全局。
6. 事务 / EOS 实现路径
| MQ | 事务模型 | EOS(Exactly Once)支持 | 关键机制 |
|---|---|---|---|
| Kafka | 跨分区事务(Producer-side)+ read_committed Consumer | ✅ Source Connect → Kafka EOS;Streams EOS v2 | 幂等 Producer(PID + Epoch + 序列号)+ Transaction Coordinator(两阶段提交,元数据写 __transaction_state) |
| RabbitMQ | AMQP 内建 tx.select / tx.commit(性能差,不推荐)/ Publisher Confirms(推荐) | ❌(Publisher Confirms 只保 At Least Once) | 应用侧自实现幂等 |
| RocketMQ | 半消息事务(two-phase commit + 回查) | ✅ 半消息保 send 一次,幂等消费保 At-Most-Once | Half Message → Commit / Rollback → 定时回查事务状态 |
| Pulsar | 跨 Topic 事务(Transaction Coordinator) | ✅ 类似 Kafka 的 Producer-Consumer 链路 EOS | 类 Kafka 两阶段提交 |
| Redis Stream | MULTI/EXEC(内存事务) | ❌ | 应用侧 + Lua 脚本 |
| NATS JetStream | 单消息原子(无跨 stream 事务) | At Least Once + 客户端去重 | DoubleAck / DiscardPolicy |
EOS 三件套对照(最常考):
| 步骤 | Kafka | RocketMQ | Pulsar |
|---|---|---|---|
| 防 Producer 重发 | 幂等 Producer(PID + 序列号) | 半消息 + 回查 | 幂等 Producer |
| 跨分区原子提交 | Transaction Coordinator + __transaction_state | Broker 端事务表 | Transaction Coordinator |
| Consumer 过滤未提交 | isolation.level=read_committed | 自动过滤 PREPARE 状态 | read_committed 行为内置 |
7. 延迟消息支持
| MQ | 延迟支持 | 实现 | 限制 |
|---|---|---|---|
| Kafka | ❌ 原生不支持 | 需要外部组件(KSQL Time-based Trigger / 自建 delay topic 轮转 / [Apache Pulsar 风格 KIP-XXX 仍未落地]) | 业务需自实现 |
| RabbitMQ | ✅ 支持 | TTL + DLX 经典方案;或 rabbitmq-delayed-message-exchange 插件 | 延迟时间长会占用大量内存 |
| RocketMQ | ✅ 原生支持(核心强项) | 18 个固定级别(1s/5s/...2h),5.x 起支持任意秒级 | 5.0 之前只能预设级别 |
| Pulsar | ✅ 原生支持 | deliverAfter(Duration) 或 deliverAt(timestamp),秒级 | 时间太久会有调度精度问题 |
| Redis Stream | ❌ | 用 ZSET + 轮询模拟 | 自实现 |
| NATS JetStream | ❌ 直接不支持 | 用客户端定时投递 | 自实现 |
速记:RocketMQ 是延迟消息的王者;Kafka 想做延迟最简单的办法是「每 5 分钟一个轮转 Topic」+ 调度器搬运。
8. 死信 / 重试机制
| MQ | 死信支持 | 重试机制 |
|---|---|---|
| Kafka | ❌ 原生无;Streams / Connect 内建 DLQ Topic;客户端通常自建 <topic>.dlq | 客户端循环 pause/resume;或 Connect 的 errors.tolerance=all |
| RabbitMQ | ✅ x-dead-letter-exchange + x-dead-letter-routing-key | reject + requeue / DLX 链路重投 |
| RocketMQ | ✅ %RETRY%<group> + %DLQ%<group> | 16 次自动重试,每次延迟级别递增 |
| Pulsar | ✅ Built-in retry letter topic + dead letter topic | negativeAcknowledge 触发重试,超 maxRedeliver 进 DLQ |
| Redis Stream | ❌(PEL + XCLAIM 模拟) | XCLAIM / XAUTOCLAIM 抢未 ACK 消息 |
| NATS JetStream | ✅ MaxDeliver + DLQ subject | NACK + maxDeliver |
9. 架构(计算与存储是否分离)
| MQ | 架构 | 弹性扩缩 |
|---|---|---|
| Kafka | 耦合:Broker = 计算(协议处理)+ 存储(segment 文件) | 加 Broker 需要 reassignment 搬数据,慢 |
| RabbitMQ | 耦合 | 集群扩缩复杂,多用「联邦 / Shovel」 |
| RocketMQ | 耦合(Broker 全功能) | 加 Broker 需要 nameserver 注册 + 主题再分配 |
| Pulsar | 分离:Broker(无状态)+ BookKeeper(存储) + ZooKeeper / Etcd(元数据) | Broker 无状态秒级扩缩;BookKeeper 独立扩存储 |
| Redis Stream | 耦合(Redis 进程内) | 用 Redis Cluster 分片 |
| NATS JetStream | 耦合 | RAFT cluster 整体扩缩 |
Pulsar 分离架构的好处与代价:
Pulsar 架构(计算 / 存储分离)
┌───────────────────────────┐
│ Broker (无状态,可秒级扩) │ ←─→ ZooKeeper/Etcd 元数据
└──────────────┬────────────┘
│
┌──────────────▼─────────────┐
│ BookKeeper Bookie 集群 │ ←─→ 副本写入(Quorum)
│ (存储层独立横向扩展) │
└────────────────────────────┘
好处:
- Broker 故障不影响数据
- 流量爆发时只扩 Broker(无需搬数据)
- 存储瓶颈时只扩 Bookie
代价:
- 多一层 BookKeeper 要运维
- 端到端跳数 +1(延迟略高)
- ZooKeeper 仍是 Pulsar 的强依赖(Pulsar 3.x 引入 Oxia 替换中)10. 元数据管理
| MQ | 元数据存储 | 演进 |
|---|---|---|
| Kafka | ZK 时代:Apache ZooKeeper;KRaft 时代:内嵌 __cluster_metadata Topic(Raft) | 2.8 Preview → 3.3 GA → 4.0 完全移除 ZK |
| RabbitMQ | Mnesia(Erlang 内嵌)→ 3.10+ 推荐 Khepri(Raft) | Khepri 解决 Mnesia 的脑裂问题 |
| RocketMQ | NameServer(无状态、轻量、最终一致)+ 5.x DLedger Controller | NameServer 是 RocketMQ 设计上的亮点 |
| Pulsar | ZooKeeper(强依赖)→ 3.x 引入 Oxia(Raft)替换 ZK | Pulsar Functions / Stats 也走元数据 |
| Redis Stream | Redis 主从复制 + Sentinel | 简单 |
| NATS JetStream | 内嵌 RAFT 集群 | 简单清晰 |
11. 延迟与吞吐基准(典型量级)
注意:所有数字仅是同等硬件下的「典型量级」,与磁盘类型 / 网络 / 客户端线程数 / 消息大小强相关。请把它当成「数量级估计」,不要当成绝对结论。
| MQ | 单机持续吞吐 | 端到端 p99 延迟 | 单 Topic 分区数上限(实际经验) |
|---|---|---|---|
| Kafka | 数百 MB/s ~ GB/s(NVMe) | 10ms ~ 50ms | 单集群 20 万+,单 Broker 4000+(KRaft 后大幅提升) |
| RabbitMQ Classic | 数万 ~ 数十万 msg/s | 1ms ~ 5ms(最低) | 数千队列,几万就要警惕 Erlang 调度 |
| RabbitMQ Quorum | 几万 msg/s | 5ms ~ 20ms | 数千 |
| RabbitMQ Stream | 接近 Kafka 水平(几百 MB/s) | 10ms ~ 30ms | 数千 |
| RocketMQ | 数百 MB/s | 10ms ~ 30ms | 上万 |
| Pulsar | 数百 MB/s | 10ms ~ 30ms(多一跳 Bookie) | 几十万 |
| Redis Stream | 几十万 ~ 百万 msg/s(受内存) | <1ms | 由内存决定 |
| NATS JetStream | 数十万 msg/s | <1ms ~ 5ms | 几万 |
速记:
想要最低延迟(亚毫秒):Redis Stream / NATS Core。 想要最高吞吐(GB/s)+ 长期保留:Kafka / Pulsar。 想要业务路由灵活 + 工业级稳定:RabbitMQ。 想要业务消息(顺序 / 事务 / 延迟)一站式:RocketMQ。
12. 生态与多语言客户端
| MQ | 官方客户端 | 第三方常用 | 流处理 / 衍生 |
|---|---|---|---|
| Kafka | Java(官方)、librdkafka(C/C++、事实多语言基石) | confluent-kafka(py/.NET/Go/Node)、sarama / segmentio kafka-go、kafkajs | Kafka Streams / ksqlDB / Connect / Schema Registry / MirrorMaker 2 / Cruise Control / Strimzi |
| RabbitMQ | Java / .NET / Python (pika) / Go (amqp091-go) | NodeJS amqplib | Streams 客户端 |
| RocketMQ | Java(官方)、5.x gRPC 协议后多语言 | Go / Python / .NET 三方 | RocketMQ Streams / EventBridge |
| Pulsar | Java / Python / Go / C++ / .NET 全家桶 | NodeJS 第三方 | Pulsar Functions / Pulsar IO / SQL(Trino 接 BookKeeper) |
| Redis Stream | redis-py / Jedis / Lettuce / go-redis | 通用 Redis 客户端 | 无(用 RedisGears) |
| NATS JetStream | nats.go / nats.py / nats.java / nats.js / nats.net 等官方多语言齐全 | — | NATS Server 内置 stream + KV + Object |
13. 运维复杂度
| MQ | 入门难度 | 集群部署 | 监控 | 升级 | 多机房 |
|---|---|---|---|---|---|
| Kafka | ★★★ | KRaft 后简化(无需 ZK),但 Broker 配置项多 | JMX → Prometheus 完善 | 滚动升级;老 → 新协议有迁移工具 | MirrorMaker 2 / Confluent Replicator / Cluster Linking |
| RabbitMQ | ★★ | Erlang 集群(cookie + cluster_formation) | Prometheus 插件 | 多版本兼容 | Federation / Shovel |
| RocketMQ | ★★★ | NameServer + Broker 主从 / DLedger | Prometheus / Console | 滚动升级 | 多 NameServer 跨地域 |
| Pulsar | ★★★★ | Broker + BookKeeper + ZooKeeper / Oxia 三件套 | Prometheus | 滚动升级 | 内置 Geo-Replication |
| Redis Stream | ★ | Sentinel / Cluster | RedisInsight / Prometheus | 滚动 | 用 Redis 跨数据中心方案 |
| NATS JetStream | ★ | 单二进制 + RAFT 集群 | Prometheus exporter 内置 | 滚动 | Leaf Node + Mirroring |
14. 典型场景适配矩阵
✅ = 强烈推荐,✔ = 可以选,△ = 不太合适,✗ = 不要选。
| 场景 | Kafka | RabbitMQ | RocketMQ | Pulsar | Redis Stream | NATS JS |
|---|---|---|---|---|---|---|
| 业务异步解耦(毫秒级延迟) | ✔ | ✅ | ✔ | ✔ | ✔ | ✅ |
| 数据总线 / 多消费方共享 | ✅ | △ | ✔ | ✅ | ✗ | ✔ |
| 大数据流处理 / 实时数仓 | ✅ | ✗ | ✔ | ✅ | ✗ | △ |
| 日志收集 / 集中聚合 | ✅ | △ | ✔ | ✅ | △ | ✔ |
| 顺序消息(业务 Key 维度) | ✅ | ✔ | ✅ | ✅ | ✔ | ✔ |
| 严格全局顺序 | △ | ✔(单队列) | ✔(单 Queue) | ✔ | ✔ | ✔ |
| 复杂路由 / 多 binding | △ | ✅ | ✔(Tag/SQL) | △ | ✗ | ✅(Subject 通配) |
| 业务事务消息(半消息) | ✔(EOS) | △ | ✅ | ✔ | ✗ | △ |
| 延迟消息 | ✗ 自实现 | ✔ 插件 | ✅ 原生 | ✅ 原生 | △ ZSET 自实现 | △ 自实现 |
| RPC 风格请求-响应 | ✗ | ✅ | ✔ | △ | ✗ | ✅ Core NATS |
| 大消息(MB 级别) | △(不推荐 >1MB) | △ | △ | ✔ | ✗ | △ |
| 跨数据中心同步 | ✔(MM2) | ✔(Federation) | ✔ | ✅ Geo-Replication | △ | ✔(Leaf) |
| IoT 大量小消息 | ✔ | ✔(MQTT 插件) | ✔ | ✔(MQTT 网关) | ✔ | ✅(NATS 协议天生 IoT) |
| 微服务事件总线(CQRS / ES) | ✅ | ✔ | ✔ | ✅ | △ | ✔ |
| 仅在 Redis 上加点 MQ | ✗ | ✗ | ✗ | ✗ | ✅ | ✗ |
| K8s / 边缘 / 资源极少 | △ | △ | △ | △ | ✔ | ✅ |
15. 详细对比章节
15.1 章节 A:Kafka vs RabbitMQ
这是最经典的「日志总线」 vs 「智能交换机」之争。本质区别是消息从哪里出来。
A.1 核心模型差
RabbitMQ:
Producer ──→ Exchange ──(routing key 匹配)──→ Queue ──→ Consumer (push)
│
└─ 路由智能在 Broker
└─ Broker 是「邮局分拣中心」,分拣完就把信塞到收件人邮箱
Kafka:
Producer ──→ Topic[Partition by Key]
↑
Consumer 主动拉(pull)
│
└─ Broker 只是「图书馆」,按 Partition 顺序写日志
└─ 消费 = 读者自己去找书架翻到第几页A.2 何时选 RabbitMQ
- 业务有复杂路由需求(同一条消息按 routing key 路由到 N 个队列)
- 需要RPC 风格的请求-响应(rabbitmq RPC pattern)
- 消息量不大(< 几万 QPS),但延迟要求亚毫秒
- 想要优先级队列、死信 / 延迟开箱即用
- 团队熟悉 AMQP
A.3 何时选 Kafka
- 需要长期可重放(debug 回放、新服务上线读历史)
- 多消费方共享同一份数据(Consumer Group 之间互不影响)
- 吞吐量级 GB/s
- 上游下游有流处理 / 数仓 / 数据科学需求
A.4 共同坑
- 生产者过快 → 消费者跟不上:RabbitMQ 队列堆积撑爆内存;Kafka Lag 爆炸但不会撑爆 Broker(保留期内是磁盘容量问题)
- 顺序消费:两个都要保证「单队列 / 单分区」消费端单线程
A.5 我该选谁
如果你正在做的是**「电商订单服务异步通知库存 / 风控 / 短信」这种业务异步**——RabbitMQ 更顺手。 如果你正在做的是**「业务订单事件 → 存数仓 → 实时风控 → 实时大屏」这种一份数据多吃**——Kafka 更顺手。 一个公司经常两个都用:业务用 RabbitMQ,数据总线用 Kafka,井水不犯河水。
15.2 章节 B:Kafka vs RocketMQ
RocketMQ 是阿里在 2011 年内部从 Kafka 0.7 fork 后针对电商场景大改而来的,所以两者底层非常像(CommitLog / 顺序写 / PageCache 都同源),但业务能力差异巨大。
B.1 同源点
| 同源 | 表现 |
|---|---|
| 顺序追加日志 | RocketMQ CommitLog = Kafka segment |
| 主从副本 | RocketMQ DLedger(Raft)≈ Kafka KRaft |
| 拉模型 | RocketMQ PushConsumer 内部其实是长轮询 |
| Group 消费 | Cluster 模式 ≈ Kafka Consumer Group |
B.2 RocketMQ 比 Kafka「业务友好」的地方
| 特性 | Kafka | RocketMQ |
|---|---|---|
| Tag 过滤 | ❌ 客户端过滤 | ✅ 服务端按 Tag / SQL92 过滤,节省网络 |
| 延迟消息 | ❌ 自实现 | ✅ 原生(5.x 起秒级) |
| 半消息事务 | 跨分区事务 | 半消息 + 回查,业务侧最自然的「转账 → MQ → 入库」事务模型 |
| 消息轨迹 | ❌ 自建 | ✅ MessageTrace 内置 |
| 重试 + DLQ | 客户端自建 | ✅ %RETRY%<group> + %DLQ%<group> 内置 |
| 顺序消息 | 单分区 | 内置 OrderlyConsumer,按 Hash 选 MessageQueue |
B.3 Kafka 比 RocketMQ「数据强」的地方
- 生态:Kafka Streams / ksqlDB / Connect / Schema Registry / MirrorMaker 2 / Strimzi 全家桶;RocketMQ 5.x 才有 Streams,生态薄
- 多语言:Kafka librdkafka 生态成熟;RocketMQ 5.x 之前 .NET / Go / Python 是「能用但弱」
- 吞吐天花板:Kafka 在百万 QPS / GB/s 这个量级文档与案例更多
- 元数据 KRaft:RocketMQ NameServer 简单是优势也是限制,跨集群迁移没 Kafka 灵活
B.4 我该选谁
国内 + 业务消息为主 + 团队熟 Java:RocketMQ。 数据总线 / 大数据 / 多语言团队 / 国际化:Kafka。
15.3 章节 C:Kafka vs Pulsar
Pulsar 是 Yahoo 2016 年开源的「下一代消息系统」,最大卖点是计算与存储分离。
C.1 架构对照
| 维度 | Kafka | Pulsar |
|---|---|---|
| 计算 | Broker 进程(含存储) | Broker(无状态) |
| 存储 | Broker 本地磁盘(segment) | BookKeeper Bookie 集群(Ledger) |
| 元数据 | KRaft(内嵌 Raft) | ZooKeeper / Oxia |
| 副本 | Topic 级 ISR | BookKeeper Quorum 写(Qw / Qa) |
| 多租户 | 弱(靠 ACL + Quota) | 强(Tenant / Namespace / Topic 三级) |
| Geo-Replication | MirrorMaker 2 / Cluster Linking | 内置(geo-replication) |
| Tiered Storage | 3.6+ Early Access | 原生支持(一开始就有) |
C.2 Pulsar 的优势
- Broker 无状态 → 加 Broker 不需要数据迁移,秒级完成
- 存储独立扩 → 突然来一波数据,加 Bookie 即可
- 多租户原生 → SaaS 场景天然隔离
- 跨地域复制 → 集群间一行配置开启
- 支持 4 种 Subscription Type(Exclusive / Shared / Failover / Key_Shared),比 Kafka Consumer Group 更灵活
C.3 Pulsar 的代价
- 运维 3 个组件(Broker + BookKeeper + ZK/Oxia),比 Kafka 多一倍
- 端到端延迟略高(多一跳 Bookie 写)
- 生态 / 社区中文资料比 Kafka 少
- 客户端历史 Bug 多(早期 Python / Go SDK 稳定性曾被诟病,3.x 已大幅改善)
C.4 我该选谁
从零起步 + SaaS 多租户 / 跨地域 / 弹性强:Pulsar 值得投入。 已有 Kafka 体系、生态依赖深:继续 Kafka,无需迁移。 运维团队 < 5 人 / 不想踩 BookKeeper 的坑:Kafka 更稳。
15.4 章节 D:Kafka vs Redis Stream
一个是「重型分布式日志平台」,一个是「Redis 内置的轻量流」,根本不是同量级的。
D.1 何时用 Redis Stream
- 业务里已经在用 Redis,临时需要点队列能力(不想引入新中间件)
- 消息量不大(百万级 / 天,而不是百万级 / 秒)
- 延迟要求亚毫秒
- 不需要长期保留(XADD MAXLEN 截断到几十万条)
- 团队不想运维另一套系统
D.2 何时用 Kafka
- 任何一项以上的「不」反过来 → Kafka
D.3 边界点
- Redis Stream 的 PEL(Pending Entries List)类似 Kafka 的「未提交 offset」概念,但断电后受 AOF 持久化策略影响
- Redis Cluster 的分片是 16384 个 slot,stream 在哪个 slot 就在哪个 master,不能跨 slot 顺序保证
D.4 我该选谁
「我只是想不用 Kafka 把消息异步起来」→ Redis Stream。 「我有任何长期保留 / 多消费方 / 流处理需求」→ 老老实实 Kafka。
15.5 章节 E:Kafka vs NATS JetStream
NATS 是 Cloud Native Computing Foundation 的项目,主打轻量 + 云原生 + 边缘;JetStream 是其持久化能力扩展。
E.1 NATS 的优势
- 单二进制部署(小到 15MB),跑在边缘 / IoT 设备无压力
- Subject 通配符路由(
a.b.>)服务端匹配,比 Kafka 灵活 - 延迟极低(NATS Core 亚毫秒)
- K8s 原生(CNCF 项目)
- 运维超简单(无 ZK 依赖,Raft 内嵌)
E.2 NATS 的劣势
- 生态弱(流处理 / 数仓 / Connect 几乎没有)
- 大吞吐场景案例少(不是说不行,是社区案例规模不如 Kafka)
- 历史数据回放能力弱于 Kafka(基于 stream max bytes / messages / age 的截断)
E.3 我该选谁
K8s + 微服务 + 边缘 + 多协议(NATS、MQTT、WebSocket)+ 极低延迟:NATS JetStream。 大数据 + 长期可重放 + 流处理 + 上下游生态丰富:Kafka。
16. 「场景 → 推荐 MQ」决策树
┌─ 是否需要长期保留(>7天)+ 可重放?
│ ├ 是 → Kafka / Pulsar
│ └ 否 ↓
│
┌─ 是否需要服务端复杂路由(routing key / tag / SQL)?
│ ├ 是 → RabbitMQ / RocketMQ / NATS(subject 通配)
│ └ 否 ↓
│
┌─ 是否需要业务事务(半消息 / 转账 + MQ + 入库一致性)?
│ ├ 是 → RocketMQ(最自然)/ Kafka EOS / Pulsar Tx
│ └ 否 ↓
│
┌─ 是否需要延迟消息(秒级 ~ 小时级)?
│ ├ 是 → RocketMQ(原生)/ Pulsar deliverAt / RabbitMQ 插件
│ └ 否 ↓
│
┌─ 业务体量与团队规模?
│ ├ QPS 极小 / 已用 Redis → Redis Stream
│ ├ 边缘 / K8s / 极小资源 → NATS JetStream
│ ├ 中规模业务 / 多语言客户端 → RabbitMQ
│ ├ 国内电商业务为主 / 团队 Java → RocketMQ
│ ├ 多消费方 / 数据总线 / 流处理 → Kafka
│ └ 多租户 SaaS / 跨地域 / 弹性 → Pulsar
└──16.1 文字版「我该选谁」总结
业务异步 + 复杂路由:RabbitMQ 是最稳的选择。 业务异步 + 顺序 / 事务 / 延迟一站式:RocketMQ。 数据总线 + 流处理 + 多消费方共享:Kafka 是事实标准。 多租户 + 跨地域 + 弹性扩缩:Pulsar 最合适,但接受 3 组件运维成本。 轻量 + 不想引入新中间件 + 已用 Redis:Redis Stream。 K8s 边缘 + 极简运维 + 多协议:NATS JetStream。
一图流:六大 MQ 全景图
📌 本附录的姐妹篇:
appendix_cheatsheet.md— 命令 / 参数 / JMX 速查appendix_pitfalls.md— 25+ 真实踩坑案例interview.md— 面试题总索引- 各章正文中的「📌 与其他 MQ 的区别」小框 — 与本附录互为索引