ARTICLE DETAIL

资讯详情

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

从Kafka到Pulsar:消息中间件选型与生产实践深度解析

从Kafka到Pulsar:消息中间件选型与生产实践深度解析 做消息中间件选型这些年我有一个很深的感受很多时候团队纠结的并不是“用哪个”而是“为什么换”和“换了之后怎么把老问题一起带走”。这次COSCon‘25同场活动里Pulsar Developer Day的议程一出来我第一时间就翻完了说实话这个活动对正在Kafka、RabbitMQ、RocketMQ之间犹豫的团队来说是一个很好的观察窗口。Apache Pulsar作为一个存算分离架构的消息中间件这几年在云原生场景下的热度一直没降过它到底解决了哪些别人解决不了的问题以及开发者社区现在最关心什么这篇文章我想结合这份议程把我自己的理解、踩过的坑、还有实际用下来的体会一次说清楚。先说结论如果你所在团队的消息量已经大到开始频繁调整分区、扩容集群、处理堆积告警或者你正在为“削峰填谷”以外的需求——比如事件重放、多租户隔离、跨地域容灾——寻找答案那Pulsar值得你花一个下午认真研究。这篇文章适合刚好想入门消息中间件的新手也适合已经跑了几年Kafka、正打算对比迁移方案的架构师。1. 消息中间件选型背后的真实痛点很多开发者第一次接触消息中间件都是从“我要解耦”开始的。订单系统要通知库存系统、积分系统、物流系统总不能一个接口一个接口地同步调吧于是消息队列上场。但用着用着会发现消息中间件这东西难的不是写代码收发消息而是后面那一堆运维问题。1.1 消息中间件到底解决了什么问题往大了说消息中间件干的是三件事异步解耦、流量削峰、数据分发。异步解耦让系统之间的依赖不再是一根硬邦邦的HTTP链子削峰填谷能让上游瞬时流量先进队列下游根据自己的处理能力慢慢消费数据分发则是把一份消息扇出给多个系统各自按需消费。但这里有个容易忽略的点前两点是“基础设施”层面的价值第三点才是区分产品能力的试金石。比如Kafka天生适合做日志类的大吞吐顺序追加但让多个业务团队共享同一个Kafka集群分区数量一多运维就开始头大RocketMQ在事务消息和延迟消息上做得顺手但在跨地域复制和分层存储上能力边界也比较明显。我见过不少团队初期用一个开源MQ就够等业务量上来开始遇到一堆“别人家没有”的问题扩容要动分区数分区数定了就定死了消费堆积想重放历史消息发现消息早被清了不同部门想共用一套集群隔离和配额又说不清楚。这些问题的根源往往不是某个中间件“不好”而是架构模型对云化、规模化场景的支持力度不够。1.2 从Kafka到Pulsar选型到底在比什么我们做一个不吹不黑的对比。Kafka的核心模型是一个分区一个日志文件分区在broker上是有状态的Broker之间靠复制协议同步数据。这个模型决定了Kafka的吞吐量可以做得非常漂亮但也带来了两个硬约束第一分区数上去了每个分区的文件句柄和内存开销会摊薄整体性能第二Broker故障时分区Leader切换依赖ZooKeeper协调虽然现在KRaft模式正在改进但对老运维来说那个“重启一个Broker要小心翼翼”的手感还是记忆犹新。Pulsar走的是另一条路。它把服务层和存储层拆开了Broker只管收发消息、处理协议、做流控是无状态的真正的数据存在BookKeeper里BookKeeper的每个存储节点只管append日志并且按段ledger滑动滚动。Broker可以随时扩缩容存储节点可以独立扩容两者互不拖累。这种存算分离的架构放在云原生环境下就是降维打击。K8s里跑Pulsar数据节点和计算节点分开扩资源利用率能算得明明白白而Kafka在K8s里跑StatefulSet那套折腾过的兄弟都懂。1.3 为什么Pulsar的社区活动值得关注消息中间件领域这几年的开源活动不少但Pulsar Developer Day这类活动有一个独特价值它把“内核开发者”和“一线使用者”放在同一个会场里。你既能听到社区核心committer讲最新功能背后的设计思路也能听到美团、腾讯、智联招聘这些真实用户讲他们踩过的坑和沉淀的实践。这和我们平时看的博客性质不一样。博客讲“怎么做”开发者日的分享更多讲“为什么这么做”和“做的时候遇到了什么”。比如一个session讲Pulsar的IO隔离光看文档你知道Broker会把读写流量分开但线上流量突增时读路径被写路径拖垮到底怎么排查这种经验只有实战过的人才讲得出来。所以这篇解读我打算把议程里的技术主题拆开并结合我自己的实践把那些藏在标题背后的内容点给你看。你去了能听懂聊什么不去也能知道这个圈子现在在关注什么。2. Pulsar核心特性拆解不只是又一个消息队列很多第一次接触Pulsar的人第一反应是“又一个消息队列”。这个印象不准确。Pulsar的设计目标其实比“队列”大得多它想做的是统一的消息流平台——队列模型、流模型、存储模型都能在一个系统里体现而且所有这些能力都建立在一套可扩展的底层存储之上。2.1 存算分离架构到底解决了什么问题用一个生活类比来说。传统消息中间件像一家餐厅每个服务员既要记菜名计算又要上菜收桌子存储客人一多服务员累死加人也没用因为餐桌就那么多。Pulsar的存算分离就像后厨和前厅分开前厅服务员可以随便加后厨的灶台也可以单独扩各管各的事。具体到技术层面Pulsar的Broker是一个无状态的接入层它主要干三件事接收生产者的消息、把消息写入BookKeeper、把消息分发给消费者。由于Broker不持有数据水平扩容就是加机器这么简单不需要重平衡数据。消息数据在BookKeeper里按ledger存储ledger是一个追加写的日志段写入会同步刷到多个bookie节点上保证副本数。这个模型带来的第一个红利是扩容体验。Kafka扩Broker通常意味着分区重分配数据要在节点间搬来搬去窗口期要盯监控。Pulsar扩Broker节点加完就完事新连接自动被负载均衡过去线上业务没有任何感知。第二个红利是IO隔离。Pulsar的读写路径在存储层天然分开写路径走BookKeeper读路径由Broker直接从存储里读取并缓存这意味着你不需要像Kafka那样把整个分区的数据都塞在page cache里才能保证读取性能。读多写少的场景Pulsar的缓存命中率会比Kafka好控制。2.2 多租户与分层存储让运维松口气的设计微服务架构普及之后公司内部的消息集群通常不是只有一套业务在用。以前用Kafka一个团队想共用集群就得开一堆Topic然后靠命名规范加上权限控制来“假装”隔离。Pulsar原生支持多租户租户tenant是顶层隔离单元每个租户下面可以建多个命名空间namespace命名空间里可以配置各自的存储配额、消息保留策略、权限角色。这意味着什么意味着不同部门之间可以真正共享一套Pulsar集群但每个部门只能看到自己的命名空间。配额超了监管告警精准到租户权限配置可以精确到“这个应用只能写这个Topic只能从这条消费者订阅里读”。对于有几十条业务线的中型公司这是实打实的运维减负。再说分层存储。Kafka的日志保留时间长了磁盘成本压不住短了需要重放历史数据的场景又不满足。Pulsar的架构天生方便做分层消息写入BookKeeper后超过一定时间或大小的数据段会自动卸载到S3、GCS这类对象存储里。消费端还是按老Topic、老订阅来读数据在哪个层对用户透明。这个能力对一个做数据回放的核心系统真的太管用了。比如做风控或审计需要查三个月前的某笔订单的事件流Kafka大概率已经不给你留了对象存储里有的话你已经找不到入口了Pulsar配合分层存储把“无限留存”变成了一个配置项而不是一个运维事故预案。2.3 为什么“消息中间件”正在向“流平台”演进现在的业务系统对事件数据的需求越来越多样。不仅今天要消费明天可能还要重放不但要实时算还要能回溯到某个历史时间点重新算一遍。如果一个系统只能“读一次”或“最多存几天”它本质上只是管道不是数据资产。Pulsar把消息默认持久化而且支持消息重播rewind消费者可以按时间或按消息ID重新读取这让“事件流”变成了一个可以反复利用的数据底座。另外一个被很多团队忽略的点是Pulsar的订阅模型。它同时支持独占订阅、共享订阅、故障转移订阅和Key_Shared订阅。一个Topic既可以被一个消费者独占拉取形成有序消费也可以被一组消费者共享分摊负载同一份数据还能同时喂给实时计算任务的多个实例。这种灵活的消费模型让Pulsar既能当削峰填谷的队列用也能当实时流计算的数据源用。线上会话保持比如WebSocket网关协调、分布式锁协调是Pulsar生态里另一个高频使用场景。Pulsar早期版本就内置了基于游标管理的跨地域复制和通过Broker分发实现的“纯粹分布式”消息队列能力现在配合Pulsar Functions、Pulsar IO连接器框架它离“统一流处理平台”的定位越来越近了。3. Developer Day议程背后的技术看点这次Pulsar Developer Day的议程从主题分布上能看出社区现在的关注重心。结合我自己了解的历次活动和社区讨论这几个方向大概率是大家最想听、也最能带回去直接用的。3.1 核心链路生产到消费的端到端性能调优开发者日里最难“水”的一类分享端到端性能调优一定排在前面。一个消息从Producer发出来到Consumer拿到手中间要经过网络传输、Broker接入、BookKeeper落盘、Broker分发这几个环节。任何一个环节出现短板整个链路的延迟和吞吐就上不去。常见的新手问题是从Producer端就埋雷。比如发送模式用了同步发送每条消息都等确认吞吐自然上不来比如批量参数设置不合理客户端攒不够batchSize就一直不发延迟假高。又比如生产者没有做消息去重课上讲幂等生产者的时候没注意业务重试时消息重复投递下游消费端又没做幂等线上数据就花了。消费端的问题也不太一样。共享订阅的消费者数量设置不合理分区数不够消费者数量再多也没用单条消息处理时间太长又没有开并发拉取整个订阅的消费速率就被最慢的那个消费者拖住了。诸如此类的问题听有实战经验的人带着压测数据和监控曲线讲一遍比自己回去看文档要省好几天时间。3.2 实践案例类分享最值得关注的三个方向结合Pulsar社区这几年的落地情况案例类分享最值得关注的通常是这三个方向。第一个是“从Kafka迁移到Pulsar”的路径复盘。这个方向的分享者一般会讲清楚两件事如何通过Kafka兼容协议降低迁移成本——Pulsar的Kafka API兼容层可以让你现有的Kafka客户端不换语言、不改代码只改连接地址就接上Pulsar集群以及迁移过程中消息怎么平滑切换、消费位点怎么同步、双跑期间怎么对数。这类内容对有存量Kafka系统的团队几乎是刚需。第二个是“大规模集群运营的稳定性实践”。Pulsar集群上了几十个Broker、几百个Bookie之后运维复杂度是几何级上升的。Bookie的JVM参数怎么调、ledger的写入分布怎么均衡、Broker和Bookie的机架感知怎么配置才能让副本分散到不同故障域这些都是文档里不会细讲、论坛里有人问但答案不全的东西。第三个是“实时数仓和事件驱动架构里Pulsar的角色”。现在很多公司把Pulsar当成实时数据管道的数据基座上游数据库变更通过CDC进Pulsar下游Flink算完再回写Pulsar最后供在线服务查询。这类分享的看点不在Pulsar本身而在它如何和Flink、CDC工具、数据湖做整体编排听完对整个数据链路的理解都会有提升。3.3 生态与工具链连接器、Kafka兼容和云原生部署Pulsar能走多远很大程度取决于生态。Pulsar IO连接器体系这些年进步很大内置了几十个Source和Sink像Debezium CDC、JDBC、Elasticsearch这些常用连接器都能直接配置使用。开发者日常如果不想自己写连接器基本可以做到配置式接入。Kafka兼容这块对很多团队来说几乎是“救命稻草”。不管社区怎么讨论架构先进性公司现有的存量代码就是Kafka客户端写的重写一套的成本动辄几周。Pulsar提供了一版Kafka协议兼容handler把Pulsar Broker伪装成Kafka Broker现有Kafka客户端只需改bootstrap.servers就能接入。这个兼容层的细节做得越深入迁移阻力就越小所以开发者日里只要涉及生态的session总是坐满人。云原生部署也是绕不开的话题。现在新项目很少有愿意自建机房跑虚拟机集群的了大家都在看K8s里的表现。Pulsar官方有一套基于Helm的部署方式也用到了cert-manager做证书管理。用Helm部署Pulsar不算难难的是之后怎么把Broker的优雅停机和BookKeeper的持久化存储卷在K8s环境里调稳。这个方向的分享能给出大家普遍踩过的坑和解决路径价值是比较实在的。4. 实操经验把Pulsar用到生产环境的几个建议议程再丰富最后还是要回到自己的环境里把集群跑起来。下面这些建议是我自己从测试环境到生产环境反复折腾后觉得最值得分享的几条。4.1 部署环境和初始参数怎么定如果你只是在本机跑个Pulsar体验一下用Docker一条命令就能起个standalone实例这没什么好说的。真正要进生产第一个要明确的就是Broker和Bookie要分开部署别图省事装在一台机器上。混布虽然省机器但JVM堆、page cache、磁盘IO互相抢资源一旦出问题排查成本翻倍。BookKeeper的参数里有一个很容易被忽略的设置是journalDirectory和ledgerDirectories前者放预写日志journal后者放实际消息数据。生产建议把两者放到不同的物理磁盘上这样可以避免写日志和写数据互相争抢磁盘IO。之前就有团队图省事都放一块盘服务一开大流量就频繁毛刺换盘后立刻稳定了。Broker端的JVM堆不要盲目给大。Pulsar Broker是个无状态接入层堆内存主要给缓存和游标管理用堆给太大反而增加GC压力。一般根据带宽和连接数估算8G到16G之间比较常见具体的值要看你的连接数量和Topic数量来压测验证。另外managedLedgerDefaultEnsembleSize、managedLedgerDefaultWriteQuorum和managedLedgerDefaultAckQuorum这三个参数决定了消息的副本数默认是2、2、2如果你的数据可靠性要求高建议改成3、3、3但也要注意磁盘空间会多三分之一。还有一个特别容易踩的坑是Broker和Bookie的时区配置。Pulsar的某些指标、日志以及跟对象存储交互时的路径命名会用到本地时间。如果集群机器时区不一致轻则日志对不上重则分层卸载的临时文件清理任务找错对象。这件事虽然简单但排查起来很费时间。4.2 常见问题与排查思路我把自己遇到过的典型问题整理成了一张速查表按着这个思路排查效率会有明显提升。问题现象常见原因排查思路生产端持续报超时Broker连接数过高或BookKeeper写入慢先看Bookie的journal写入耗时再看Broker的线程池饱和度消费端延迟持续升高消费者处理慢或分区数少于消费者数看消费者fetch速率确认每条消息的处理耗时消息丢失副本数设置过小或生产者是异步发送且未开重试查生产者发送确认模式、检查ackQuorum主题出现不可读的“系统Topic”使用Replicator跨集群复制未清理旧配置检查全局命名空间里的复制器状态集群负载不均存储节点ledger分布倾斜用pulsar-admin检查bookie的磁盘使用和ledger分布比如“消费端延迟持续升高”这个场景我曾经排查过一个问题消费者的单条消息处理耗时只有2ms但整体消费速率就是上不去。最后发现是共享订阅的消费者预取prefetch条数设置太小消费者虽然处理得快但本地buffer一直处于饥饿状态网络拉取开销成了瓶颈。把prefetch从500调到5000之后吞吐直接翻了一倍。还有一个容易让人懵的场景Topic明明没有消费者但打开管理界面发现积压消息一直在涨。这大概率是生产端在持续写入且消息保留策略设为了持续保留。Pulsar默认的消息保留策略只保留一定时间或大小如果你的命名空间里设置了无限保留积压增长其实是正常的需要根据消费需求重新评估保留策略。另外如果你用的客户端是旧版本一定要关注Broker升级时的兼容性。Pulsar对协议兼容有专门的兼容性矩阵Broker版本和客户端版本差太远可能会出现消息ID解析异常、订阅游标不兼容的问题。升级前把客户端版本统一升一升能省掉很多线上故障。4.3 什么场景我真的不建议用Pulsar聊了这么多Pulsar的优点也该说说它的不适用范围。任何技术都有边界Pulsar也不是银弹。如果你的业务消息量很小一天就几万条团队只有两三个人对多租户、分层存储这些特性完全没需求那就没必要为了用Pulsar而用Pulsar。部署一套Pulsar集群需要Broker和Bookie至少各两三个节点起步资源开销在那里摆着杀鸡用牛刀不是效率高的选择。这种情况下用云厂商提供的托管MQ或者轻量的Redis Stream反而更合适。如果你的业务消息模型极其简单就是纯削峰填谷对重放、多租户、流处理都没想法那选Kafka或RocketMQ都行它们在成熟度、社区资料、排查经验上都要更厚。Pulsar的架构优势要在大规模、多团队共享、长留存、跨地域这些维度叠加起来之后才会非常明显用不到这些维度时它的复杂度反而是负担。对于想把Pulsar用在“交易类、强一致消息场景”的团队也要留个心眼。Pulsar在消息投递语义上提供最多一次、至少一次、有效一次等选择但有效一次需要通过幂等和去重配合才能实现事务消息的支持虽然已经有了但使用场景相对狭窄不能期待它像数据库事务那样万能。设计系统时还是要围绕“异步最终一致”来思考消息中间件不是分布式事务的银弹。5. 参会前建议带着这些问题去听如果你已经决定去Pulsar Developer Day现场或关注后续资料我建议提前准备几个问题带着问题去听效率和收获会高很多。第一个值得关注的问题是分享里提到的性能优化场景和我的业务模型是否一致。线上性能问题通常跟消息大小、Topic数量、消费者模式强相关别人遇到的是大消息批量写你遇到的问题可能是小消息高并发写两者的优化方向可能完全不同。听的时候别只记结论问清楚压测时的消息大小、分区数量、消费模式才能判断能不能照搬。第二个值得关注的问题是兼容层在生产环境到底能承压多少。很多团队关心Kafka兼容协议尤其是迁移项目。但兼容和替代是两个概念兼容层能让你API兼容但是游标管理、流控行为、延迟特征还是有差异。如果分享者有压力测试数据问清楚在什么规格的集群、什么样的负载模型下测出来的这比一个空洞的“兼容性良好”要有价值得多。第三个值得关注的问题是社区版本的功能演进方向是什么。Pulsar社区一直在推进新功能比如统一的协议处理框架、轻量级事务改进、BookKeeper的日志压缩优化等。了解这些演进方向可以帮助你做技术选型时判断风险你要用的功能在社区版本里是稳定的还是实验性的维护活跃度如何要不要引入商业支持这些判断做对了能少走很多弯路。6. 我对Pulsar生态落地现状的一些体会Apache Pulsar从2018年左右开始被国内大厂采用到现在海外社区也在持续升温它的发展路径其实很像所有优秀开源项目共通的路先解决少数技术领先团队的极端问题再逐渐把能力产品化、生态化最终让普通团队也能用上它的好处。我个人在跑Pulsar集群的过程中记忆最深的一次经历是配合跨地域复制做灾备演练。两个机房之间同步消息由于网络抖动导致复制延迟上升但我发现Pulsar的复制机制不会因为网络抖动把本地消费者拖死——Broker依然正常提供本地消息服务只是复制积压了一下。这种“故障半径被隔离”的体验在以往用其他中间件做异地多活时是比较难得的。还有一个感受是社区资料的质量。中文社区这两年活跃度明显提升技术文章、用户案例、benchmark数据都越来越多了有问题去GitHub issues和社区群搜经常能看到靠谱的回复。对于开源项目来说社区健康度比单点技术亮点更能决定长期价值从这一点看Pulsar的生态是在往好的方向走的。如果你准备开始评估Pulsar我最后再给一个具体的小建议先别急着搭大集群先用standalone模式跑起来把生产、消费、重放、多租户这几个操作亲手做一遍再找一个小流量非核心业务放到共享订阅下跑一两周。感受一下它的消费模型和运维手感再做决策。技术选型这事光看文档和评测是不够的亲手用过的体感往往才是最后做决定的依据。
返回列表