与 Kafka 的选型对比
用途:为具体业务选消息基础设施时给出可论证的理由
设计目标差异
「设计目标差异」小节链接| 维度 | RocketMQ | Kafka |
|---|---|---|
| 起源目标 | 电商业务消息(事务、顺序、重试、运营可观测) | 高吞吐日志流与流处理底座 |
| 存储 | CommitLog 混合存储 + ConsumeQueue 索引;支持按 key/时间查询 | Partition 顺序段文件,零拷贝、页缓存友好 |
| 消费模型 | 组位点、Broker 侧管理、支持重试队列与死信 | 消费者组 + 客户端位点提交,重试需自建(DLQ 主题) |
| Tag/属性过滤 | Tag 与 SQL92 属性过滤在 Broker 侧生效 | 无服务端过滤(需下游或流处理层) |
| 事务 | 半消息 + 回查(面向业务事务通知) | 事务(面向 producer 精确一次写入 Kafka 内部) |
| 延迟消息 | 内置延迟级别/定时消息(版本相关) | 无原生支持,需外部实现 |
| 运维 | NameServer 轻,Broker 功能多 | 依赖 ZooKeeper 或 KRaft,分区再均衡生态成熟 |
| 生态 | 国内业务系统、与 Spring 集成 | 流处理(Flink/Streams)、日志采集、数据管道 |
什么时候选 RocketMQ
「什么时候选 RocketMQ」小节链接- 业务事件通知为主:需要重试队列、死信、消息轨迹、按业务键查询、Tag 过滤。
- 需要事务消息或延迟消息而不愿自建。
- 团队以 Java 为主、运维规模中等,希望“开箱即用”的业务消息语义。
什么时候选 Kafka
「什么时候选 Kafka」小节链接- 吞吐是首要指标(日志、埋点、大规模事件流)。
- 下游是流处理引擎(Flink/Spark Streaming/Streams),需要精确的分区语义与回放。
- 需要与数据湖/CDC/搜索索引等构建统一数据管道。
- 团队具备 Kafka 运维能力(分区数、副本、
min.insync.replicas、客户端版本治理)。
共同必须解决的问题
「共同必须解决的问题」小节链接无论选哪个,都要自己实现:
- 消费幂等(至少一次)。
- 重试与死信策略(Kafka 需自建;RocketMQ 内置但仍要配上限与告警)。
- Schema 演进与契约管理(配合 Schema Registry 或事件目录)。
- 顺序保证的范围声明(分区内有序,跨分区无序)。
- 对账与补偿(消息系统不能证明业务最终正确)。
常见误区
「常见误区」小节链接| 误区 | 修正 |
|---|---|
| 用“哪个吞吐高”一句话选型 | 先看语义需求(重试/过滤/事务/延迟)与运维能力 |
| 把 MQ 当数据库(长期堆积不回查) | 保留期有限,业务状态要以 DB 为权威 |
| 认为 Kafka 支持恰好一次所以不用幂等 | 端到端仍取决于 sink 与消费者实现 |
| 一个 Topic 承载所有事件 | 语义与保留策略混杂,按域拆 Topic 并定义契约 |
| 忽视消息体积规范 | 大消息拖垮吞吐与延迟,改传引用 + 回查 |
延伸阅读
「延伸阅读」小节链接- Apache Kafka 与 RocketMQ 官方文档(架构与语义章节)
- Martin Kleppmann《数据密集型应用系统设计》第 10-11 章