ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Pulsar重塑消息队列:存储计算分离与多协议实践解析

Pulsar重塑消息队列:存储计算分离与多协议实践解析 “Make MQ Great Again”这个口号出现在 COSCon‘25 与 Pulsar Developer Day 2025 的联合会场上多少有些让人会心一笑。作为一个从 ActiveMQ 时代写消费端出身、后来又折腾过 Kafka 和 RocketMQ 的后端我对这个消息队列的“文艺复兴”主题既熟悉又好奇。消息中间件这个看似基础、看似稳定的领域在数据量爆炸、云原生普及、AI 应用大规模落地的当下正在经历一场并不喧哗但非常硬核的重塑。这篇回顾写的是我全程参加这场活动后的所见、所闻和所得既有会场里的高密度技术分享也有我在现场亲手跑通的小实验还有一些会后回来自己验证过的经验。如果你想了解 Pulsar 为什么能在 2025 年重新把 MQ 这个老话题讲出新内容或者正在为团队选型消息系统而纠结这篇内容应该能给你一些参考。1. 开场印象MQ 不是“老古董”而是正在换发动机1.1 为什么“Make MQ Great Again”不是一句调侃活动公布主题时很多人在群里转发“Make MQ Great Again”第一反应都是玩梗。但到了现场听了几场分享之后我意识到这句话其实很认真。消息队列并不是一个需要“再次伟大”的过气组件恰恰相反它在现代分布式系统里的位置比十年前更重要。过去我们聊 MQ主要是在聊削峰填谷、异步解耦、应用间通信现在聊 MQ大家关心的是实时数仓的接入层、AI Agent 的上下文传递、物联网设备的海量事件接入、跨云跨地域的数据同步。基础能力没变但承载的业务场景已经换了一代。会场上有一张 PPT 我记得很清楚把现存主流消息系统的演进按时间轴排列传统企业级 MQ、开源消息中间件、分布式日志系统、云原生消息平台依次出现。Pulsar 属于最后那一档但它并不是简单地“再做一款 Kafka”而是把底层存储、计算、协议接入彻底拆开。这个架构动机在多个演讲里被反复强调让一套引擎同时满足队列模型和流模型既保留消息确认、死信、顺序消费这类 MQ 老用户离不开的语义又提供流式系统需要的分区、重放、高吞吐和水平扩展。现场有不少人问“Pulsar 是不是要取代 Kafka”几乎每个讲师都会先纠正这个问题。更准确的说法是Pulsar 想在 MQ 和流处理之间找到平衡点。Kafka 在流处理生态的地位短期内难以撼动但很多企业的真实场景其实是混合型的一部分流量要求低延迟、强一致的消息投递另一部分流量需要长时间保留、可回溯的流数据。传统方案通常要同时维护两套系统而 Pulsar 试图用存储和计算分离的架构让一套系统覆盖两种模式。这也是活动主题叫“Make MQ Great Again”的原因——不是在怀旧而是给 MQ 换一套新发动机。1.2 联合场次的价值开源大会与开发者日擦出的火花这次是和 COSCon 合办会场设置很有意思。COSCon 本身是综合性开源大会观众里有很多做前端、AI、操作系统、开源的伙伴Pulsar Developer Day 则更垂直吸引的是消息系统和数据基础设施的深度用户。两个群体放在一起产生了很奇妙的化学反应。一个做辅助驾驶系统的工程师和一个做量化交易平台的架构师竟然在同一个圆桌上聊 Pulsar 的背压机制一个刚接触消息队列的大学生在动手实验区用二十分钟起了本地集群眼睛里全是光。这种组合让 Pulsar 的开发者也意识到消息中间件的使用者正在变得更多元不再只是后端老炮。AI 应用需要把大模型调用记录、工具调用事件、多轮会话上下文全部以事件流的方式存储和分发IoT 平台需要面向海量设备维持百万级长连接同时还要把设备状态变更可靠地同步到业务系统。这些新场景没有那么多历史包袱反而更愿意尝试新架构。活动上好几场演讲的主题都集中在这些新用例上而不是单纯讲“我们比谁吞吐高”。联合办会的好处就在这里做开源的人能找到真实需求用开源的人能找到落地路径。2. 关键技术分享拆解Pulsar 的“新三样”2.1 存储计算分离为什么是必答题而不是选答题Pulsar 最核心的设计就是 Broker 和 BookKeeper 分离。Broker 只负责协议解析、鉴权、路由和缓存真正持久化数据的是一组独立的 BookKeeper 节点。这个架构让扩容变得非常优雅需要提升读写吞吐就扩 Broker需要增加存储容量或磁盘带宽就扩 BookKeeper两者完全独立。现场有讲师把这种设计类比成“餐厅后厨和中央厨房分离”Broker 是前厅的传菜口BookKeeper 是集中做菜的中央厨房高峰期可以直接加传菜口的人手而不需要把整个后厨翻新一遍。对比之下传统消息集群通常是“一体的”每个节点既处理请求又负责在本地磁盘上写数据。集群扩到一定规模后某个节点磁盘满了或 IO 被打满处理能力就立刻形成瓶颈。存储计算分离不是新概念但在消息领域把这个概念做成真正稳定大规模落地的Pulsar 算是最彻底的一个。BookKeeper 的 Segment 存储模型把数据切成小段分布在多个节点上配合 Quorum 机制保证多副本写入。当一个 BookKeeper 节点故障时系统自动把该节点的 Segment 重新复制到其他节点整个过程对 Broker 和客户端透明。我在现场最关心的其实是这个架构在日常运维里的真实表现。有位分享嘉宾给了组数据他们在 100 多个 BookKeeper 节点上长期运行生产集群单日消息量超过万亿条。让我印象更深的不是数字本身而是他提到“扩存储节点就像加一块普通硬盘一样”不用迁移既有分区不用重新做数据均衡。这一点对运维团队非常友好也是很多开源 MQ 在规模化之后最痛的点。2.2 多协议接入把“兼容”从口号变成可配置项Pulsar 原生支持多协议这件事以前只是在文档里看到这次现场演示让我彻底信服了。同一个 Pulsar 集群可以同时用 Kafka 协议客户端、Pulsar 原生协议、MQTT 协议、AMQP 协议接入。演示的工程师现场开了一个 Kafka 的 console consumer 直接消费 Pulsar topic 里的消息又从 MQTT 客户端发布了一条遥测数据两边的消息能在同一个 topic 上汇合。底下的观众先是安静了一会儿随后开始密集提问这个兼容是只做协议翻译还是语义也完整映射答案比较令人安心Kafka 协议兼容层不是简单地把字节流转换一下而是尽量对齐了消费组、offset 提交、事务等核心语义。这意味着团队里已有的 Kafka 客户端、监控工具、甚至部分 Flink Connector 都可以直接连到 Pulsar 上迁移成本被大幅压缩。MQTT 的支持则带了一堆额外的性能调优参数比如 QoS 级别、保留消息、遗嘱消息那些从 EMQX 之类的生态迁过来的用户会觉得很亲切。这种多协议策略有一个特别实际的价值公司内部往往同时有好几套消息系统因为不同部门各自选型形成了 Kafka、RabbitMQ、Pulsar 甚至老牌企业级 MQ 并存的局面。Pulsar 通过协议层粘合让新老系统之间可以逐步迁移而非一次性推倒重来。现场有个比喻我很认同多协议不是让你把所有鸡蛋放进一个篮子而是给你一个可以慢慢搬家的中转站。2.3 分层存储与无状态 Broker成本视角下的杀手锏过去消息系统很难做到长期保存历史数据要么存储成本过高要么消费历史消息会把集群压垮。Pulsar 的分层存储把热数据放在 BookKeeper冷数据可以自动卸载到对象存储比如 AWS S3、腾讯云 COS以及各类兼容 S3 的存储。这个能力听起来很轻松实际背后是两个硬核设计一是 Broker 可以只缓存热数据的索引和元数据二是数据卸载和回读的流程完全自动化应用层不需要感知。现场展示了一个很“凡尔赛”的操作把一个 topic 的 retention 设置成“不删除”然后生产了几百万条消息等数据自动从 BookKeeper 卸载到对象存储后再用一个刚启动的全新消费组从头开始消费。消费过程中流量水位非常平没有明显的读取毛刺。这套机制意味着我们可以真正把 MQ 当作一个“流式数据湖”的入口而不是用完即弃的临时管道。也正是因为 Broker 无状态Pulsar 在 Kubernetes 上跑得非常顺。Pod 调度、滚动升级、故障自愈都不需要关心本地数据。现场动手实验环节主办方用的就是一套 Kind 集群一条命令部署了 Pulsar Operator然后通过 CRD 申请了一个三 BookKeeper、三 Broker 的集群。从提交 YAML 到集群 Ready 大概花了三四分钟这个速度对开发者体验来说相当重要。3. 动手实验与实操记录从零跑通一个 Pulsar 集群3.1 实验环境准备Docker Compose 快速起飞在活动动手区主办方准备了好几台实验机器配置不算高8 核 16G 内存。大多数人第一选择是用 Docker Compose 快速起一个 standalone 集群。这条路径对初学者最友好也是我建议第一次接触 Pulsar 的朋友先尝试的方式。下面是我在现场用到的启动文件片段回来之后我在自己电脑上又验证了一遍可以直接用。version: 3.8 services: pulsar: image: apachepulsar/pulsar:4.0.0 container_name: pulsar ports: - 6650:6650 - 8080:8080 environment: PULSAR_MEM: -Xms512m -Xmx512m -XX:MaxDirectMemorySize256m command: bin/pulsar standalone启动只需要两分钟docker compose up -d docker exec -it pulsar bin/pulsar-admin clusters list看到standalone输出就说明服务已经起来了。这里要注意新版 Pulsar 的 standalone 模式和旧版细节差异比较大一些老文章中让改standalone.conf的配置在这里不一定生效建议优先查看官方文档里对应版本的部分。启动后可以立刻跑一个生产消费的连通性验证docker exec -it pulsar bin/pulsar-client produce persist://public/default/test -m hello coscon -n 1 docker exec -it pulsar bin/pulsar-client consume persist://public/default/test -n 1 -p Earliest这个步骤顺利的话你会看到一条消息从生产到消费的全过程。现场很多第一次摸 Pulsar 的朋友在这一步就消除了陌生感原来消息队列的体验可以这么轻。之后再用pulsar-admin topics stats看 topic 的详细统计就能直观理解消息队列的内部状态长什么样。3.2 用 Pulsar Operator 在 Kind 里部署集群Docker Compose 适合体验但如果你关注的是 K8s 环境下的真实运维那一定得试试 Pulsar Operator。在实验区我们通过 Kind 创建了一个包含一个控制平面和三个工作节点的集群然后安装证书管理器、Pulsar Operator再提交一个自定义资源。核心操作大致如下kind create cluster --name pulsar-demo --config - EOF kind: Cluster apiVersion: kind.x-k8s.io/v1alpha4 nodes: - role: control-plane - role: worker - role: worker - role: worker EOF部署 Operator 后创建一个PulsarCluster资源apiVersion: pulsar.apache.org/v1alpha1 kind: PulsarCluster metadata: name: demo-pulsar spec: broker: replicas: 3 image: apachepulsar/pulsar:4.0.0 bookkeeper: replicas: 3 image: apachepulsar/pulsar:4.0.0 volumes: - name: data emptyDir: {}等 Pod 都变成 Running 后把 Broker 服务端口转发出来接上文同样的pulsar-client命令就能访问。现场有人问为什么不用emptyDir来做生产环境答案显然是演示环境不在乎数据持久化生产环境一定会用 PVC 挂独立存储卷。这里想提醒大家Operator 只是把繁琐的部署逻辑封装了但它不会替你决定存储方案网络策略资源配额这些依然要按生产标准来设计。3.3 性能验证小规模也能看出架构差异动手实验区给我最大的惊喜不是“能跑”而是能自己动手做简单的压测验证架构行为。主办方给每个小组发了脚本用 Pulsar 自带的pulsar-perf工具进行生产压测。我在 3 个 Broker 和 3 个 BookKeeper 的小集群上跑了一组对比先只扩 Broker 节点保持 BookKeeper 不变发现生产吞吐能明显上涨然后只扩 BookKeeper 节点但扩大存储吞吐能力和磁盘数量之后积压消费的恢复速度更快了。命令本身很简单docker exec -it pulsar bin/pulsar-perf produce -r 100000 -s 1024 -t persist://public/default/perf-topic现场跑出的吞吐是每秒钟十几万条消息单条消息 1KB客户端和集群都在同一台机器上。这个数字不算夸张但它验证了一个关键结论在存储计算分离架构下Broker 和存储可以独立调优。对于做技术选型的人来说这种可拆分性意味着预算可以花在真正需要的地方。我还试着调低了 BookKeeper 的写入副本数从默认的 3 降到 2生产延迟立刻下降但可用性也下降。这种亲手体验比看任何 benchmark 图都更能帮助你理解“副本数不是越多越好而是要在一致性、延迟和成本之间做权衡”。4. 社区圆桌与开发者生态项目是代码更是秩序4.1 从“用 Pulsar”到“改 Pulsar”的成长路径圆桌环节请了几位长期活跃的社区贡献者其中一位分享了自己从用户到提交者再到 PMC 成员的经历。他最早只是在公司里负责维护 Pulsar 集群遇到一个 订阅模式相关的 bug提了个 issue后来被引导去修复一个较小的 broker 端并发问题。过程并不神秘先去读pulsar-broker模块的代码跑相关测试然后提交 PR。从第一个 PR 到成为核心贡献者他用了大约两年。他提到一个很实用的建议新手贡献者别一上来就选设计类的大 issue先从标注good first issue的入手比如完善监控指标、修文档、补测试用例。这类任务能让你快速理解模块边界。Pulsar 社区里有一条不成文的规则一个补丁的价值不仅在于修复正确还在于你是否补充了清晰的测试和变更日志。社区 Review discussions 会对代码风格、异常处理、性能影响抠得很细但不会对新人苛刻到劝退。这个环节对我这样的普通用户也很有启发。参与开源不只是为了刷简历而是当你真正理解了代码逻辑之后你在排查生产故障时会有完全不同的直觉。我过去遇到 broker 内存上涨第一反应是加内存后来才学会从缓存配置、订阅积压、Backlog 大小这些角度去排查而这些认知正是通过读社区代码和讨论学到的。4.2 用户案例车联网、量化交易与 AI Agent社区圆桌之后是几个真实用户案例的闪电分享。第一个案例来自智能汽车行业车端设备通过 MQTT 接入 Pulsar每天产生数亿条车辆状态事件包括电池SOC、定位、告警、OTA升级状态。他们的需求很典型不同生命周期的事件有不同的优先级车辆实时告警需要秒级投递而历史轨迹数据需要长期保留用于模型训练。Pulsar 的多协议和分层存储正好命中这两个需求一套集群同时处理在线和离线链路。另一个案例让我印象很深是一家量化交易团队。他们的消息系统不仅要快还要在极端行情下不能丢消息。该团队用 Pulsar 做订单事件和行情数据的异步分发频率不算高但每条消息都价值巨大。他们重点用到了 Pulsar 的事务消息能力和精确一次语义并定制了 Broker 的线程模型参数把端到端延迟控制在个位数毫秒级别。这个案例说明MQ 在某些场景下不是“尽力而为”的工具而是必须能提供强保证的分布式基础设施。AI Agent 场景被多次提及很有意思。Agent 需要同时维护多个外部工具调用和多个会话上下文相当于一个复杂的异步并发系统。Pulsar 在这里被用作事件总线记录 Agent 的每次决策、工具执行结果和用户反馈。这种数据天然是流式的需要支持回溯、重放和按时间线消费。相比传统“应用日志 搜索存储”的方案消息队列给 AI 应用提供了一种更结构化、更可靠的事件基础设施。可以预见 2026 年会有更多 AI Infra 团队把 Pulsar 纳入技术栈。5. 常见问题与答疑实录现场高频问题整理5.1 消息积压、重复消费与顺序性现场答疑环节高频问题仍然围绕消息队列“老三样”积压怎么办、重复消息怎么处理、顺序性怎么保证。有位朋友问“积压几百万条消息能不能直接把分区数调大来加速消费”这个问题很典型。Pulsar 的分区扩容方式与 Kafka 相似扩容之后通过增加消费者并发确实能提升吞吐但积压不只是消费端并发问题还要看下游系统能不能扛住压力。我的建议一直是优先确认 Backlog 是否已经触发 Retention 策略避免数据被清理然后通过监控看是消费者处理慢还是 Broker 分发有瓶颈。Pulsar 提供了比较完善的 Backlog 指标也可以用pulsar-admin topics stats查看每个订阅的msgBacklog和blockedSubscriptionOnUnackedMessages。如果是因为下游处理能力不足盲目加消费者只会把下游压垮。更稳妥的方式是先扩容下游再逐步增加消费者实例并配合按累计积压量自动伸缩的机制。重复消费这个问题Pulsar 可以从两个层面回答消息确认语义支持最多一次、至少一次和精确一次事务消息能保证一批消息的原子性写入但对下游来说仍然建议在消费者里做幂等设计。顺序性则要按需取舍Pulsar 支持按 key 哈希到单个分区来保证同一 key 的消息顺序但这会损失单个分区的写入并行度。没有任何消息系统能在“全局顺序、无限并行、高性能”三个维度同时拉满必须在建模阶段想清楚需求边界。5.2 集群运维元数据存储、故障替换与版本升级很多人关心 Pulsar 依赖 ZooKeeper 或 etcd 做元数据存储这件事。在 4.x 时代Pulsar 默认还会使用 ZooKeeper但社区正在推动用 etcd 作为替代减少外部依赖。现场运维专家建议生产环境不要把元数据服务和其他业务混部并确保定期备份。虽然元数据量不大但一旦损坏整个集群的服务发现和主题元数据都会受影响。版本升级是另一个高频问题。Pulsar 的版本迭代比较快跨大版本升级时要注意 broker 与 bookkeeper 之间的兼容性。社区给出的经验是升级前先阅读 release notes尤其是配置项变更和移除项然后用金丝雀升级的方式先升级一个 broker 观察稳定再逐步推进。BookKeeper 的升级通常需要滚动重启但 Pulsar 可以做到不停机前提是读写在升级过程中不能关。很多升级事故都出在顺序上比如先升级了 ZooKeeper 又回到旧版这种来回横跳很容易造成 meta 信息不兼容。现场也有人问“能不能直接从一个 Kafka 集群平滑迁移到 Pulsar”。答案是可以做但过程需要规划。比较推荐的路径是先用 Pulsar 的 Kafka 协议兼容层让新集群“伪装”成 Kafka endpoint然后通过双写切换最后再裁剪旧集群。这套方案的核心收益是迁移过程中不需要修改客户端代码也不需要对生产流量做激进的割接。6. 一些会后想补充的个人经验活动结束后我又花了两天时间在自己本地环境里复现了动手实验中的主要操作顺便测试了几个现场来不及做的功能。这里想分享一个很小的经验很多人看到 Pulsar 的组件清单Broker、BookKeeper、ZooKeeper、Proxy会觉得很重但实际上跑一个开发测试环境远比想象中轻。官方 Docker 镜像里标准包已经自动完成了配置组装甚至连pulsar standalone这样的命令都帮你把元数据服务一并拉起了。真正值得花时间研究的不是“怎么启动”而是“生产环境里如何把每个组件的职责边界划清楚”。另一个体会是消息中间件这个领域其实特别需要“场景驱动”的学习方式。只看架构图、只对着文档调参很难真正理解为什么存储计算分离有意义。我建议你先从自己的业务出发找一个痛点比如“历史消息无法回溯”“扩容总需要搬迁数据”“多个协议客户端无法统一接入”然后带着问题去 Pulsar 文档里找答案。你会发现自己对消息系统的理解会从“会用一个工具”变成“能设计一套消息基础设施”。最后再分享一件小事。圆桌结尾有观众问“Pulsar 社区未来一年最希望看到什么变化”一位维护者想了想说“希望更多新场景的人来‘折腾’我们而不是只要求我们变得更像老牌 MQ。”这句话让我挺触动的。消息队列从来不应该是保守的代名词它值得在新架构、新场景里被重新发明一遍。如果你也在关注 MQ 的演进希望这篇回顾能让你感受到下一次技术选型时除了“用哪个老牌中间件”我们还可以有更多值得认真评估的选项。
返回列表