Kafka、Pulsar 与 RocketMQ 选型对比:架构差异与决策边界
从存储与计算耦合方式对比 Kafka、Pulsar 与 RocketMQ 的架构差异,给出大数据链路选型判据
袋鼠云
三者选型的核心分歧不在功能清单,而在存储与计算的耦合方式。结论:Kafka 把分区日志与 broker 计算耦合在同一节点上,运维简单、生态最重;Pulsar 用 broker 加 BookKeeper 做存算分离,弹性与多租户最强但组件最多;RocketMQ 用 NameServer 加 Broker 的轻量路由架构,事务消息与业务语义最全。大数据链路默认选 Kafka,有多租户或跨地域扩展需求才考虑 Pulsar,需要事务消息与业务解耦才选 RocketMQ。
维度一:存储与计算的耦合方式
- Kafka:以分区为核心,每个分区的日志段存储在 leader broker 所在节点的本地磁盘上。存储与计算耦合,扩展存储就必须扩展计算,分区再平衡会触发数据迁移。
- Pulsar:broker 是无状态计算层,数据以 ledger 段的形式写入 BookKeeper 集群,存储与计算完全解耦。存储扩容独立于计算扩容,segment 级数据可以按策略分层。
- RocketMQ:NameServer 只维护路由元数据(轻量、无状态、不参与数据读写),Broker 负责消息存储与读写,消息按 CommitLog 顺序写盘,再拆出消费队列索引。整体架构介于两者之间:比 Kafka 简单,比 Pulsar 组件少。
机制深挖:扩容与积压时发生了什么
- Kafka 扩容:分区数固定后增加 broker,需要分区再平衡,历史数据会随之迁移;若 broker 数少于分区数,单 broker 承担多个分区,容易出现数据分布不均。消费侧还有 rebalance 问题:消费组实例变化时组内所有消费者会暂停,等待 rebalance 完成。
- Pulsar 扩容:存储扩容是加 bookie,后续写入的新数据落到新增 bookie 上的新 ledger 段,不需要像 Kafka 那样迁移历史分区数据。代价是同一 ledger 的 fragment 会带状分布在多个 bookie 上,读写会在多个 bookie 之间跳跃。
- Pulsar 的积压代价:broker 分发消息默认走 managed ledger 缓存,积压超过缓存后 broker 要从 bookie 读,延迟上升。"存储扩容独立"不等于"积压免费",消费积压治理仍是必修项。
- ledger 生命周期:topic 的存储抽象是 managed ledger,内部由多个 ledger 组成;ledger 关闭后只能以只读方式打开,全部 cursor 消费完后整个 ledger 可以删除,这是过期清理与分层存储的机制基础。cursor(订阅位点)同样持久化在 BookKeeper,broker 重启不丢消费进度。
维度二:一致性语义
- Kafka:通过
acks配置(0、1、all)、幂等生产者与事务机制,在 Kafka 生态内部提供精确一次的端到端语义,消费端以 offset 提交为界。 - Pulsar:默认至少一次,自 2.8 起提供事务 API,订阅 ack 与 cursor 管理恢复点。
- RocketMQ:提供同步刷盘、异步刷盘与主从同步策略来控制可靠性等级;事务消息采用"半消息"机制保证本地事务与消息发送的一致性;消费失败走重试队列与死信队列。
维度三:消费模型
- Kafka:消费组加 offset,分区与消费者一一对应,扩容靠加分区;同一条消息不能被多个业务独立消费,需要复制多套 topic。
- Pulsar:topic 上可挂多个独立订阅(exclusive、failover、shared、key_shared),同一份数据可被多组消费者以不同语义消费;key_shared 在共享模式下保留同 key 有序。
- RocketMQ:消费组模型,支持集群消费与广播消费两种模式;原生支持延迟消息与消息轨迹。
实时开发 StreamWorks
覆盖采集、开发、运维全链路的云原生一站式实时数据开发平台
一致性与消费的机制补充
- Kafka 的顺序边界:顺序只在分区内保证,没有全局有序。副本机制上每个分区有一个 leader,写入与消费都走 leader,follower 只做同步复制,leader 故障后由 follower 接管。offset 是不断递增的整数并持久化在 Kafka 中,消费者重启后从上次位置继续;"重复消费"主要发生在宕机或重启后 offset 未提交的场景。Kafka 原生不支持延时消息,消费顺序按写入顺序执行。
- RocketMQ 的路由与存储:NameServer 各节点之间不互相通信,只负责元数据与路由管理;Broker 与所有 NameServer 保持长连接并定时注册 Topic 路由。消息以 MessageQueue 为物理管理单位实现水平扩展,offset 为定长存储(Java Long),队列视为无限长数组、offset 是下标。可靠性语义是至少一次传递,顺序性靠单队列 FIFO 保证。
- RocketMQ 延迟消息的边界:开源版不支持任意时间精度的延迟消息,只支持预置的 level。若业务要"延迟 17 分钟"这类非标时长,要么用预置 level 近似,要么自己用定时任务兜底,这条经常在选型阶段被忽略。
维度四:生态绑定
- Kafka:Connector 生态最全,Flink、Spark、各类湖仓表格式(如 Paimon、Iceberg、Hudi)与 CDC 工具的集成最成熟,是大数据领域的事实标准。
- Pulsar:提供 Pulsar IO 与 Functions,Flink、Spark 连接器可用,但社区规模与第三方集成数量明显少于 Kafka。
- RocketMQ:生态集中在业务消息场景,Spring Cloud Stream 有官方支持;大数据侧有 Flink connector,但使用面窄于 Kafka。
维度五:运维复杂度
- Kafka:组件最少(broker,以及 ZooKeeper 或 KRaft 模式下的自管理元数据),团队学习成本最低,人才储备最多。
- Pulsar:需要同时维护 broker、BookKeeper bookie 与元数据服务(ZooKeeper 或 etcd),组件最多,运维门槛最高。
- RocketMQ:NameServer 加 Broker 两层,部署与运维轻量,但集群规模大后的调优资料相对少。
先进制造
围绕交付履约、设备效率、质量追溯与供应协同,帮助制造企业看清生产过程、管住交付风险、提升运营效率。
把机制差异翻译成选型信号
- 扩容是否需要迁移历史数据:需要则 Kafka 的扩容成本高,不需要则 Pulsar 占优。
- 是否存在长时间积压的可能(大促、离线回灌):积压会让 Pulsar 走从 bookie 读的路径,Kafka 依赖本地磁盘顺序读,两者退化方式不同,压测必须覆盖积压场景。
- 是否要求任意时长延迟消息或完整业务重试语义:是则倾向 RocketMQ,同时确认其开源版延迟消息只支持预置 level。
- 是否有多个业务组独立消费同一份数据:是则 Pulsar 的多订阅最省事,Kafka 需要复制多套 topic,存储成本成倍增加。
决策边界
- 大数据流式入湖、CDC 管道、日志采集:选 Kafka。生态集成成本最低,社区问题资料最多。
- 多租户隔离、跨地域复制、存储与计算独立扩容:选 Pulsar。这些能力是架构原生支持,Kafka 需要额外手段补齐。
- 业务解耦、事务消息、延迟消息、消费重试与死信语义:选 RocketMQ。这些业务消息语义是它的设计重心。
- 团队规模小、运维人力有限:优先 Kafka 或 RocketMQ,不要为用不到的能力背上 Pulsar 的运维成本。
两个容易被忽略的边界
- 不要用功能清单打分选型:三者都能做到"发出去、消费掉",差异在故障与扩容时的退化路径。评估时应设计故障注入场景(broker 宕机、消费组 rebalance、存储积压),比较恢复行为,而不是比较功能数量。
- 迁移成本是架构问题的一部分:从 Kafka 迁往 Pulsar 或 RocketMQ 不是换客户端那么简单,消费语义(offset 提交、订阅模型、ack 方式)都要重新对齐,大数据链路的迁移应按 topic 分批推进并保留双跑窗口。
选型检查清单
- 下游消费者数量:多业务独立消费同一份数据时,Pulsar 的多订阅优势才显现
- 是否需要事务消息或延迟消息,是则倾向 RocketMQ
- 是否已有 Flink、Spark 湖仓链路,是则 Kafka 集成成本最低
- 存储扩容是否必须与计算解耦,是则倾向 Pulsar
- 运维团队是否具备维护三类以上组件的能力,这决定 Pulsar 是否可行
- 是否有跨机房或跨地域部署需求,是则考察 Pulsar 的 geo-replication


