☰
Pulsar vs Kafka:消息中间件架构演进与开发者日实践观察
2026/10/20 13:08:46 网站建设 项目流程

最近我们组在做内部消息中台的第二轮技术评估,群里又因为“Kafka 还是 Pulsar”争得不可开交。正巧看到 COSCon‘25 同场活动 Pulsar Developer Day 倒计时 3 天的消息,标题里“聚焦消息中间件创新实践”这行字让我精神一振。对正在做技术选型、或者已经上了 Pulsar 但想挖深实践细节的人来说,这种活动比关起门来啃文档要高效得多。Pulsar 这个项目这几年的存在感越来越强,但它到底解决了什么问题、适合什么场景、又有哪些让人踩坑的地方,很多人其实还没完全想清楚。借着这个倒计时的节点,我把这些年做消息中间件调研和落地的经验整理一遍,也顺便说说我准备在 Pulsar Developer Day 上重点关注的几个方向。

1. 消息中间件重选型:为什么 Pulsar 又回到关注中心

1.1 选型常见的三个误区

先聊一个我观察很久的现象:很多团队选消息中间件,思路还停留在五年前。第一个误区是只盯着峰值吞吐的数字对比,Kafka 号称能扛百万级 TPS,Pulsar 在某些 benchmark 里也不相上下,但真实业务场景根本不是单一维度的比拼。第二个误区是盲目跟随生态惯性,团队里有人熟 Kafka 就全员用 Kafka,完全不管业务是不是真的需要那样的模型。第三个误区是看到 Pulsar 组件多、部署复杂就直接劝退,这个我承认它确实比单体中间件重,但重有重的理由,关键是看这个“重”能不能换回长期收益。

我过去参与的几个项目里,消息中间件的使用场景差异极大。有的系统一天只有几十万条消息,用最简单的 RabbitMQ 就能很舒服;有的系统要支撑千万级设备的消息接入,同时还要做流式处理和实时计算;还有的是典型的内部事件总线,多个业务团队共用一套集群,彼此之间还有隔离要求。把这几类需求放在一起看就会发现,Pulsar 经常在最复杂的那一类场景里胜出,因为它的设计目标一开始就是冲着“云原生时代的消息系统”去的,而不是老一代中间件的简单升级。

1.2 Pulsar 的“存算分离”到底解决了什么

先说结论:Pulsar 对消息中间件最大的贡献是把存储从计算节点里拆了出来。Kafka 的模型是每个分区挂在某个 broker 上,数据写进本地磁盘,broker 挂了以后分区需要重新选举和复制。Pulsar 的模型则是 broker 只负责收发消息、管理订阅和路由,真正的消息数据写入底层的 BookKeeper 集群。这个拆分的价值体现在几个方面。

第一,broker 变得无状态了。无状态的意思是你可以随时把某个 broker 摘掉,不会导致任何数据丢失,因为数据根本不在它身上。扩容的时候加 broker 就行,缩容的时候直接下线节点,不用像 Kafka 那样小心翼翼地做分区重平衡。第二,存储扩容和计算扩容是独立的。业务高峰期可以只扩 broker 来提升吞吐,存储吃紧的时候可以只扩 BookKeeper 节点,甚至可以不动本地集群,直接把老数据卸载到对象存储。第三,故障恢复速度完全不一样。Kafka 一个节点挂了,上面几百个分区的 leader 要逐个重新选举,数据要重新复制,整个过程以分钟计;Pulsar 的 broker 挂了对下层数据毫无影响,新节点几十秒内就能顶上。

这也是为什么我最近在内部讨论里越来越倾向 Pulsar——不是因为它比 Kafka 快,而是因为它的运行模型更符合当前基础设施的演进方向。现代基础设施已经把“无状态服务”这件事验证得很透彻了,存储交给专门的存储系统,计算交给专门的计算系统,消息中间件终于也走到了这一步。

1.3 一张表看清主流中间件的定位差异

维度KafkaPulsarRabbitMQRocketMQ
核心模型分区日志分层订阅 + 分段存储队列 + 交换机队列 + 事务消息
存算状态存储绑定 broker计算存储分离存储绑定节点存储绑定节点
多租户靠 Topic 命名和 ACL原生 Tenant/Namespace靠 VHost靠 Group
消息回溯按 offset 回溯按时间/位置回溯,支持无限保留有限场景按时间回溯
跨地域复制MirrorMaker原生多集群复制插件实现原生支持
运维复杂度中等偏高(组件多)低中等
最适配场景流处理、日志管道混合队列与流、多租户平台企业内部路由交易消息、顺序消息

这张表不用看得太细,核心是要抓住一个判断逻辑:如果你的场景是“日志管道 + 流处理”,Kafka 仍然是靠谱选择;如果你的场景是“很多团队共用一套消息平台,既要队列语义又要流式语义,还要考虑跨机房和存储成本”,Pulsar 的架构优势会越来越明显。RabbitMQ 和 RocketMQ 各自有自己的舒适区,但它们和 Pulsar 的竞争关系其实不算强,真正和 Pulsar 正面竞争的是 Kafka 这个量级的选手。

2. Pulsar 架构创新的核心:Broker 无状态化与分层存储的设计逻辑

2.1 Broker 无状态:弹性伸缩和故障恢复从“重”变“轻”

我最早看 Pulsar 源码的时候,最困惑的就是 broker 到底在干什么。它不存数据,那消息是怎么从生产者到消费者手里的?答案是用 BookKeeper 做中间存储。生产者把消息发给 broker,broker 把消息追加写入 BookKeeper 的一个 ledger 里,同时更新 cursor 信息,消费者从 broker 拉取时,broker 再从 BookKeeper 读出来。整个过程里,broker 更像是一个聪明的路由器加缓存层。

这带来的直接好处就是弹性伸缩变得非常轻。我见过一个真实案例:某个业务做秒杀活动,平时集群只有 5 个 broker,活动当天临时加到 20 个,整个过程就是点几下“扩容”按钮,新 broker 起来后自动加入集群,不需要提前预估分区数,不需要把 topic 重新分配。活动结束再缩回 5 个,也没有任何数据迁移的成本。这在 Kafka 里是不可想象的——你必须在创建 topic 的时候就定好分区数,分区绑定了 broker,扩容以后老分区也不会自动均匀分布。

另外一个容易被忽略的优势是版本升级。Kafka 升级需要滚动重启所有 broker,因为每个 broker 都承担数据角色,重启期间要仔细处理副本迁移。Pulsar 升级 broker 就轻松很多,一台一台重启就行,甚至可以在流量低峰直接全量替换,存储层完全无感知。运维压力是真的小一截。

2.2 BookKeeper 与分段存储:为什么数据可以无限留存

Pulsar 的存储设计里有两个关键词:ledger 和 segment。一个 topic 的写入被拆成很多个 segment,每个 segment 对应 BookKeeper 里的一个 ledger。当 segment 大小超过阈值(默认比较常见的是 128MB 或者按时间滚动),系统就自动关闭当前 ledger,创建一个新的。这个机制决定了 Pulsar 的存储是“无限可扩展”的——消息不断写,segment 不断滚动,每个 ledger 完成之后可以做副本数调整、可以做数据压缩、也可以被卸载到冷存储层。

这跟 Kafka 的“日志分段”思路有相似之处,但底层实现完全不同。Kafka 的 segment 是 broker 本地文件,受限于单机磁盘容量和复制机制;Pulsar 的 ledger 是分布式写入 BookKeeper 集群的,可以横向扩展存储节点,而且 BookKeeper 写入是“并发 + 定序”的,同一时刻可以并行写多个 ledger,吞吐能力自然不一样。

还有一个点必须提:Kafka 的消息保留时间默认是 7 天,超过就删除;Pulsar 可以配置为“永不删除”,配合分层存储把历史数据丢到对象存储里。这意味着 Pulsar 的 topic 可以真正当作一个“可回放的事件流”来用。我这边有个真实需求:风控系统要回溯三个月内的所有用户操作事件,以前用 Kafka 只能把历史数据导到数仓里,查一次费时费力。用 Pulsar 之后,直接在 topic 上按时间做回放就行,对象存储上的老数据也能无缝读回来,这种能力对做数据分析和审计的场景价值非常大。

2.3 多租户模型:平台化团队最需要的东西

如果你只需要单团队单业务用消息队列,多租户这个特性可能感受不明显。但一旦你所在的组织有多个业务线,想把消息中间件做成一个内部公共服务,Pulsar 的多租户设计就派上用场了。

Pulsar 的管理层级是 Tenant(租户)、Namespace(命名空间)、Topic(主题)三层。租户之下可以建多个命名空间,命名空间再包含多个 topic。每个命名空间可以单独配置消息保留策略、存储配额、权限策略、订阅模式。这有什么用?最直接的价值是“安全隔离 + 配额管理”。不同业务团队各自用一套命名空间,互相之间默认不可见,管理员可以按团队分配配额,某个团队写爆了不会拖垮别人。

我在之前参与的一个平台化项目里,就靠 Pulsar 的多租户能力把消息服务开放给了六个业务团队。每个团队有自己的命名空间,消息保留时间从 6 小时到 30 天各不相同,安全权限完全隔离,运维只需要关注整个集群的容量水位,不需要为每个团队单独搭环境。如果当时选的是 Kafka,就得靠一堆工具脚本加 ACL 配置来模拟这种隔离,维护成本完全不同。

2.4 跨地域复制:从“事后同步”到“原生能力”

跨机房场景里,Kafka 的标准方案是 MirrorMaker——消费一个集群的数据、再写到另一个集群。这种做法问题很明显:配置复杂、同步延迟不可控、出现循环复制还要仔细配置。Pulsar 把跨地域复制做成了内建能力,通过配置 bookie 和 broker 所属的机房信息,系统自己维护一份“本地区域集合”和“全局副本集合”,写出去的消息自动同步到其他机房的副本。

更关键的是,Pulsar 的跨地域复制是逻辑级别的,消费进度和写入进度在各机房独立推进。这意味着你可以在两个机房都搭一套 broker 集群,共享底层 BookKeeper 的多机房副本,任何一个机房挂了,另一个机房可以继续生产消费,而且整个切换逻辑可以做到对业务几乎透明。

当然,跨地域复制的配置还是有讲究的,比如要合理设置 journal 同步的 ack 策略、要预估机房间带宽、要规划好每个 topic 的副本分布。这些细节网上资料不多,很多是要现场实践才能积累的,也因此格外需要 Pulsar Developer Day 这类活动来面对面交流。

3. Pulsar Developer Day 上值得重点看的三个实践方向

3.1 从活动主题看内容方向:创新实践到底指什么

COSCon‘25 的这个 Pulsar Developer Day 从主题上看,重点落在“创新实践”四个字上。我对“创新实践”的理解是:不是单纯讲 Pulsar 有什么功能,而是讲怎么把它用到真实业务里解决实际问题。这类开发者日通常会有几个固定的内容模块:社区最新版本的核心特性解读、典型用户案例的架构复盘、动手实验环节,以及各路开发者的闪电分享。

作为参会者,我不会把注意力放在“Pulsar 又发了什么新版本”这种消息面上,那看 release notes 就够了。我更关注的是别人在真实生产环境里的取舍过程。比如同样是用 Pulsar 做消息平台,有的团队把消费模式玩出了花,有的团队在分层存储配置上总结了一套成本优化方法,有的团队踩过 BookKeeper 调优的大坑。这些才是“实践”两个字最有含金量的部分。

3.2 方向一:高吞吐低延迟场景的调优路径

Pulsar 在 benchmark 里表现很好,但落地到真实业务,调优是绕不开的。我给自己列了三个问题,准备在活动现场找答案或者跟同行交流。

第一个问题是生产者端的批量参数怎么设。Pulsar 的 producer 默认有 batching 机制,可以把多条消息攒在一起发送,提升吞吐。但 batching 设太大,单条消息的延迟会增加;设太小,吞吐又会掉下来。这个平衡点跟业务的消息体大小和流量模型强相关,没有统一答案。第二个问题是 BookKeeper 的写路径调优。ledger 的 ensemble size、write quorum、ack quorum 这几个参数决定了数据的可靠性和写入性能,默认配置能满足大多数场景,但高吞吐场景通常需要微调。第三个问题是消费者端的消息积压处理。Pulsar 的订阅模型比 Kafka 灵活得多,但积压发生后怎么快速扩容消费者而不导致消息乱序,这里面有很多实际技巧。

这些问题我在内部环境里做过一些验证,但离“最佳实践”还有距离。开发者日的好处就是你能看到别人已经趟过的路,比自己盲目试错省时间。

3.3 方向二:从 Kafka 平滑迁移到 Pulsar 的工程细节

这两年明显感觉到,越来越多团队开始认真评估“从 Kafka 迁到 Pulsar”这件事。我预判 Pulsar Developer Day 现场,这部分话题会非常热。迁移不是简单的换个客户端地址,而是一整套工程问题。

首先是协议兼容层。Pulsar 提供了 Kafka 协议兼容的入口,让存量 Kafka 客户端基本不改代码就能连上来。听起来很美好,但实际用起来有约束:部分高级特性如事务、精确的 offset 管理、某些 Consumer Group 行为需要额外配置。其次是历史消息的迁移策略。如果你需要把 Kafka 里积压的历史消息完整搬到 Pulsar,通常会走“双写 + 回放”的路径,这个过程的流量控制和一致性校验很容易出问题。再次是消费位点的转换。Kafka 的 offset 和 Pulsar 的 cursor 语义不同,迁移过程中如何保证消费不重不漏,需要精心设计。

我自己更感兴趣的其实是“不迁移”的方案——用 Pulsar 的 Kop 能力让两个系统共存,逐步把流量切过去。这种渐进式方案在真实生产环境里更稳妥,也更容易被管理层接受。如果现场有人分享这类案例,我肯定要第一时间去听。

3.4 方向三:消息存储成本治理与冷热分层

消息中间件的存储成本,很多团队一开始真没当回事,等数据量上来才发现比想象中高得多。Kafka 的数据只有一份本地副本,长期保留的成本根本扛不住,这也是为什么大多数团队只保留 7 天。Pulsar 的分层存储给了另一条路:热数据留在 BookKeeper 里,冷数据自动卸载到对象存储,对象存储的成本只有本地磁盘的十分之一甚至更低。

Pulsar 的分层存储策略配置起来也不复杂,核心是设置好 offload 的触发条件和目标存储桶,系统会自动把已经不再频繁访问的 segment 搬到对象存储。读取时如果消费者要访问冷数据,broker 会自动从对象存储拉回来。这个机制让“消息无限保留”变得真正可行。

但要特别提醒:分层存储不是配完就不管了。离线数据被重新读取时的性能跟对象存储的吞吐强相关,如果业务频繁回放超大范围的历史数据,还是要提前规划好对象存储的 bucket 分片、限流策略和缓存层。这个方向的实践经验,现场交流的价值很高。

4. 倒计时 3 天,怎样准备才能在开发者日活动里真正有收获

4.1 会前动手清单:先跑通一个本地单机环境

很多人参加技术活动,全程听讲,回去之后一个礼拜就把内容忘光了。我的习惯是:活动前先把环境跑起来,带着问题去现场,回来之后基于自己的环境立刻复现一遍。Pulsar 这点做得非常友好,官方提供 standalone 模式,一台机器就能跑完 broker + BookKeeper + 客户端,适合拿来练手。

我建议在活动开始前,花一个下午做三件事。第一,用 Docker 把 Pulsar standalone 拉起来,执行几条命令创建 tenant、namespace 和 topic,跑通生产消费。第二,用 pulsar-admin 的 CLI 尝试查看 topic 的统计信息、修改消息保留策略、触发一次分层存储 offload。第三,写一个简单的生产者消费者程序,体验一下 Pulsar 的四种订阅模式在行为上的差异。

这几件事做完,你对 Pulsar 的基础操作就有了手感。再去现场听别人讲高并发调优、架构演进,你会发现理解速度快很多,因为底层那些概念你已经亲手碰过了。而不会从头懵到尾。

4.2 带着问题去:三类值得面对面交流的问题

开发者日的现场交流,是信息密度最高的环节。但要把这个环节用好,得提前把自己工作里“卡住的地方”列出来。我把问题分成三类。

第一类是架构设计层面的:比如多租户怎么规划才合理、跨地域复制和本地优先的取舍、消息保留策略如何匹配业务审计要求。这类问题适合跟做架构设计的参会者聊。第二类是参数调优层面的:比如 batching 怎么设、ack 超时怎么调、BookKeeper 的副本参数如何与你的磁盘和网络匹配。现场如果能碰到有实战经验的人,一两句话就可能点醒你。第三类是生态整合层面的:比如 Pulsar 和 Flink 的 connector 稳定性如何、Function 在轻量计算场景里值不值得用、Kafka 兼容层在实际业务里有哪些坑。这些属于“不跑过生产环境很难知道”的信息,开发者日恰好是最容易碰到这类人的地方。

4.3 别把开发者日当成发布会:它的价值在技术生态连接

最后说一点心态上的建议。有人参加这类活动,期望值是“听完一场讲座就掌握一门技术”,这几乎不可能。任何消息中间件都不是看一两场分享就能上手的,真正的学习发生在你回到自己的开发环境、对着真实业务流量做验证的那一刻。开发者日的价值在于:它能让你看到这个技术生态的前沿方向、认识正在解决类似问题的人、Get 到那些文档里没有的细节。

所以我给“倒计时 3 天”的定义是:给自己的准备时间。花点时间把 Pulsar 的本地环境跑起来,再把自己的技术痛点列成清单。等到活动那天,你不再是旁观者,而是带着明确问题来寻找答案的参与者。这样做一次活动下来,收获比闷头读一个月文档还大。

我这次去 Pulsar Developer Day,除了上面说的调优和迁移话题,还想重点观察一下社区最近在轻量化部署上的进展。毕竟 Pulsar 的组件复杂度是绕不开的痛点,如果能在运维层面再简化一步,会有更多中小团队愿意尝试它。作为一个长期在做消息基础设施评估的人,我对它后续的发展是保持乐观的。期待现场能有一些让我眼前一亮的实践案例,到时候再写一篇更具体的复盘。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询