【架构革命】LinkedIn 也无法拯救的 Kafka:Pulsar 的存算分离成了终极答案?

引言
本文承接《重大技术转向:LinkedIn 抛弃自家创造的 Kafka,又重新造了个 Pulsar 的轮子?》,深入剖析这一技术转向的核心。当 Kafka 的诞生地 LinkedIn 高调公布 Northguard 时,整个流数据圈着实为之一震。文中列出的多出痛点看似新鲜,实则是社区多年来对 Kafka 单体架构诟病的集中爆发——所有问题都源自"存储-计算绑定"的沉重历史包袱。
然而,**Apache Pulsar 天然的存算分离架构,距今已经稳定解决这些问题已 6 年有余,并已在数万节点规模稳定运行至今。**今天,我们以 Northguard 为镜,对照 Pulsar,揭示存算分离如何成为流处理的终极答案。
LinkedIn 最近宣布,公司的日活用户已经从过去的亿级增长到了十亿级。这对他们的数据流基础设施带来了前所未有的挑战。
在其最新发布的《Introducing Northguard and Xinfra: scalable log storage at LinkedIn》博客中,LinkedIn 技术团队指出,传统的 Apache Kafka 已经无法应对如此大规模的数据需求。问题主要表现在五个方面:
系统扩容成本高且操作复杂
元数据管理成为系统瓶颈
热点负载分布不均
故障恢复速度慢
运维过程繁琐复杂
这些问题的根本原因在于 Kafka 的单体架构设计——存储和计算被紧密绑定在同一个 Broker 上。这种设计导致了三个主要缺陷:扩容时必须进行大规模数据迁移、单一控制器(Controller)易成为吞吐瓶颈、分区副本一旦失效就难以快速恢复。
为了解决这些问题,LinkedIn 开发了全新的日志存储系统 Northguard。然而,Apache Pulsar 早在设计之初就采用了存算分离的架构,已经天然避免了 Kafka 面临的这些问题。
本文就以 Northguard 提出的核心问题为线索,分别分析 Kafka 的架构缺陷、Northguard 的解决方案,以及 Apache Pulsar 如何通过存算分离实现更优雅的解决方案,看看为何 Pulsar 的存算分离成了终极答案。
梦回 2010:Kafka 无比正确的单体架构黄金时代
回望 2010 年,当 LinkedIn 的工程师们开始设计 Kafka 时,他们面临的是一个与今天截然不同的技术环境。那是一个 CPU 多核化初期、内存容量仅有 4-16GB、机械硬盘为主导、网络带宽有限(1Gbps)的硬件环境。在这样的背景下,Kafka 选择"让数据更贴近"的本地存储访问策略,减少网络开销,提高整体性能,这无疑是一个极其明智的架构决策,同时也是当时流行的技术风向。
当时的技术环境决定了单体架构的合理性。分布式系统架构尚未成熟,云计算刚刚起步,商业数据中心仍以传统的垂直扩展为主。在这种环境下,Kafka 的单体耦合设计不仅符合当时的硬件特性,更重要的是它简化了系统架构,降低了运维复杂度。

正如图中所示,Kafka 凭借其高性能的单体架构和成熟的流处理生态,实际上,迅速成为首选实时数据管道的事实标准,这一地位从 2011 年开源到 2017 年 Apache Kafka 1.0 发布期间得到了充分巩固。
时至今日,传统 Kafka 真心跟不上趟了
今时不同往日

技术发展的速度远超所有人的预期。摩尔定律在过去十五年中持续发挥作用,CPU 性能提升了数十倍,内存容量从 GB 级跃升到 TB 级,SSD 存储普及带来了数百倍的 IO 性能提升,网络带宽从 1Gbps 发展到 100Gbps 甚至更高。更关键的是,云原生技术的普及彻底改变了基础设施的游戏规则。消息弹性与成本成为关键,云原生架构要求系统具备自动化的弹性伸缩能力,这正是传统单体架构难以适应的。
与此同时,数据量的增长更是呈现爆炸式态势。从 TB 级数据增长到 PB 级,对传统分布式架构提出了前所未有的挑战。现有消息系统不合乎自适应理想,多租户场景增多,资源隔离与共享需求并存,企业内多业务线需要共享基础设施的同时保证安全隔离。这些新需求在 Kafka 设计之初是无法预见的。
更令人始料未及的是,微服务架构、容器化、Serverless 等新技术浪潮接踵而来,应接不暇。云服务的发展速度远超预期,从 2010 年的概念阶段到 2015 年的快速普及,再到今天的云原生时代,仅用了十余年时间就彻底重塑了整个 IT 基础设施。在这样的技术变革浪潮中,即使是最优秀的架构设计也难免显得力不从心。
更遑论,当时间来到 2025 年,Multi-Agent 等智能体系统的兴起为传统单体架构带来了前所未有的冲击。在这个 AI 驱动的新纪元中,数百甚至数千个智能 Agent 需要进行实时协作,它们之间的通信模式完全颠覆了传统应用的交互范式。每个 Agent 都具备独立的推理能力和决策逻辑,需要在毫秒级别内处理复杂的上下文信息、进行多轮对话、执行并行推理任务。这种高频次、高并发、高智能的通信需求,让原本为静态数据流设计的单体消息系统显得捉襟见肘。传统单体架构的局限性讲会被无限放大:单点瓶颈会阻塞整个 Agent 网络的协作流程,资源耦合导致无法针对不同 Agent 的计算和存储需求进行精细化调优,缺乏弹性扩展能力使得系统无法应对 Agent 数量的动态变化。
参考OpenAI如何去魔改 Kafka 我们就会有更加深刻和直观的认识:
分区限制所带来的性能问题 OpenAI 大量使用 Python 语言进行业务系统开发,对于高并发消费场景,一味地增加 Topic 的分区并不能从根本上解决问题;进一步地,因为 Kafka 集群支持的分区数由于本身 IO 模型而受限,过多的分区(Kafka 磁盘顺序写退化为随机写)会导致集群性能下降和延迟增加,增加分区的动作反而会带来 Kafka 集群不稳定的风险。
大人们,时代真的变了!
在这个新纪元中,企业面临着前所未有的挑战:
性能与成本的“鱼与熊掌”之争变得更加尖锐——弹性扩容、秒级扩容、按需付费、高可用、跨区域、跨部门、自动化运维、快速故障切换、冷热数据分离、按需提取等需求并存,而传统单体架构在这些方面都显得力不从心。
同时,旧瓶难装新酒的问题日益突出:单体架构的性能上不去,成本下不来——扩容困难,云原生不兼容,重平台重构建成本巨大,存储利用率低,也难以分散。更为关键的是,折小集群,艰难应对数据量的暴增——分区数受限,为跟得上资源过载,要部署大量小集群,间序与优先级高度 IOPS 下退化。
在硬件升级的红利无法享受的情况下,SSD 性能无法被分散分放,一次性区域迁移、网络流量管理、存储计算资源无法灵活分配等问题都成为了传统单体架构无法跨越的鸿沟。计算和存储资源不能独立,无法利用新技术。这些问题在大规模、高并发、智能化的 AI 时代显得尤为突出。

这也是包括 Linkedin 自己都抛弃 Kafka 的缘由,同时君不见各路大厂、各种云厂商其实都有自己的 Kafka 商业版本,这都在 Kafka 之上做魔改,痛苦的一边做分离、一边还要做兼容。时至今日,只想说一句,大人们,时代真的变了!
Kafka 架构之痛:单体设计在新时代的致命缺陷
问题 1:扩展性差:新增 Broker 需要大规模迁移数据
Kafka 的设计之初并未考虑极端规模的云原生应用场景:每个 Broker 既负责消息服务(计算),也负责数据持久化(存储),这意味着计算与存储紧耦合。在这种架构下,新增 Broker 时必须将历史数据从旧节点重平衡到新节点,耗时且耗资源。例如,在这篇研究 Kafka 扩展性问题的技术分析中就指出:在一个 3 节点集群承载约 777.6 TB 数据的场景中,扩容到 4 个节点就需要将约 194.4 TB 数据从旧节点迁移到新节点,使用 10Gb 网络需要约 43 小时才能完成数据搬迁。这样大规模的数据复制过程不仅消耗时间,也严重影响服务可用性和扩容效率。实践中,Kafka 集群往往需要停机迁移或大规模调整,严重影响业务连续性。
Northguard 来切分数据
Northguard 将日志划分为更小的段(Segment)和范围(Range),并对这些小段进行条带化分布。简单来说,Northguard 将一条日志拆成多个可独立复制的小块(Segments),每个小块可以部署在不同的 Broker 上,从而实现 I/O 负载的均衡。

这样,新加入的 Broker 无需搬迁旧有数据:随着新日志段的产生,这些段会自动分配到新 Broker。正如 Northguard 博文所示,当新 Broker 5 加入集群后,后续产生的日志段自然被分配到它,系统在后台自动将负载“自均衡”。因此,Northguard 在扩容时基本无需迁移现有数据,只要在元数据层级更新少量信息即可,大幅降低了扩容开销。

如上图所示,Northguard 的日志被分割为多个段后,新加入的 Broker(图中为 Broker 5)会直接接管后续生成的新日志段。无需移动已有段,扩容过程几乎是“热”进行的。
Pulsar 的数据就在存储层
Pulsar 从设计之初就彻底解耦了存储与计算。Pulsar 的 Broker 负责计算转发,而实际消息数据均写入独立的 BookKeeper 存储集群。这意味着扩容时无需进行大规模数据复制。

Pulsar 通过分段存储架构,使得添加 Broker 时无需实际数据重平衡或移动,因为数据存在于存储层。

Pulsar 的 Broker 只需要快速更新少量元数据来让新节点开始接手部分工作。换言之,Pulsar 实现了真正的“无停机扩容”:扩容操作仅需几秒钟完成,而不是 Kafka 那样的小时级。
从上文可以得知,Northguard 通过细颗粒度的日志条带化在扩容时避免了大规模数据搬迁;而更为根本的存算分离架构则在 Pulsar 中早已实现,彻底消除了传统 Kafka 式的重平衡需求。在“扩容即插即用”这一点上,Pulsar 的解决方案更加优雅和成熟。
问题 2:元数据瓶颈,海量分区难以支撑
Kafka 的元数据管理其实存在很严重的瓶颈。传统 Kafka 由少量 Controller(配合 ZooKeeper 或 KRaft)集中管理所有主题和分区的元数据信息。当集群中主题和分区数量达到几十万时,单一 Controller 的内存和处理能力就难以支撑,创建或删除主题时往往会引发全局阻塞(所谓“雪崩”效应)。LinkedIn 的工程师在自己的博文中就曾提到:Kafka 难以支持数十万级别的分区,元数据规模的快速膨胀成为了扩展和管理的绊脚石。
Northguard 的分布式元数据模型
Northguard 引入了分布式的元数据模型,将元数据切分为多个**虚拟节点(vnode)**并使用 Raft 复制。

每个 vnode 负责一部分主题、范围和段的元数据,通过一致性哈希分布在不同 Broker 上。这种“动态分片状态机(DS-RSM)”设计下,元数据不再集中在单个节点上,而是跨越整个集群分布。北网文章指出,这种方式消除了 Kafka 单一控制器的瓶颈,使得系统能够“支持数百万级的副本,一致性和高可用性均得到保证”。由于每个 vnode 都只需管理自己负责的那部分元数据,操作热点被分散开来,不同主题操作也互不干扰,避免了集中式控制器在高并发操作下崩溃。
Pulsar 的元数据优化
Pulsar 的 Broker 本身是无状态的,所有元数据则存储在外部服务(例如 ZooKeeper 或 etcd)中。虽然 ZooKeeper 也有节点限制,但 Pulsar 设计了多租户隔离与命名空间等机制,将不同租户和命名空间的元数据分散存储。同时 Pulsar 对元数据管理做了诸多优化,其中最为突出的是 Bundle 概念,这和 Northguard 的 vnode 环形结构的核心理念,简直如出一辙。

Bundle 的核心优势在于其“计算换空间”的设计哲学。虽然需要额外的哈希计算来确定 Topic 属于哪个 Bundle,但这种计算开销相比于元数据存储和网络传输的节省来说是微不足道的。一个典型的 Bundle 可以包含数千甚至数万个 Topic,这意味着元数据的存储和管理开销被按数量级压缩。以一个包含 100 万 Topic 的系统为例,如果每个 Bundle 包含 1000 个 Topic,那么元数据管理的复杂度就从 100 万降低到 1000,这是一个质的飞跃。
Bundle 的动态分裂机制进一步提升了系统的灵活性。当某个 Bundle 的负载过高时,Pulsar 可以自动将其分裂为多个更小的 Bundle,并将它们分配到不同的 Broker 上。这种设计使得 Pulsar 在面对热点数据时能够快速响应,而不需要像 Kafka 那样进行复杂的分区重平衡操作。更重要的是,Bundle 的分裂和合并都是在线进行的,不会影响业务的正常运行。
Pulsar 的元数据层可以通过扩容 ZooKeeper/etcd 集群来伸缩,而且主题分区的扩展只需更新元数据即可,无需移动实际数据,且由于存在多个层级的命名空间,Pulsar 可以避免单个逻辑空间内元数据集中爆发。
不过,社区很多同学还是会有疑问,那 Zookeeper 终究有“力竭”的时候呀?
其实根据根据真实调研,绝大多数用户的使用量,其 topic 数都到不了百万级,对于几十万的 topic,得益于 Pulsar 架构天然分散了压力,BookKeeper 同样在底层为元数据(如租户、命名空间、主题信息等)提供服务,并可横向扩展,绝大多数时候 Zookeeper 是胜任大数据量元数据管理工作的。大家去除 Zookeeper 的呼声来源,还是集中再减少维护工作量和降低成本上面。
总之 Northguard 通过可扩展的分片状态机彻底解决了 Kafka 元数据的瓶颈问题;Pulsar 则依赖无状态的 Broker + 外部元数据存储的设计(以及多租户隔离)来避免单点元数据压力。两者的优化也如出一辙。对用户来说,Pulsar 集群的元数据负载可通过增加存储节点而线性扩展,因此能够更轻松应对海量分区场景。
问题 3:负载热点与磁盘失衡
负载热点也是 Kafka 的固有问题。由于单个分区对应整条日志,资源分布非常粗糙:如果一个 Broker 承载了多个热门分区,就会出现局部 I/O 瓶颈和磁盘倾斜。LinkedIn 甚至需要依赖 Cruise Control 等工具来人工平衡集群负载。Linkedin 的文章中就指出:“复制单元越粗,集群资源倾斜问题就越严重……每个副本都要存储整个日志,会产生大量负载倾斜”。在这种情况下,新加入的 Broker 可能很长时间处于闲置状态,直到人工触发重新分配现有日志,运维成本高。

Northguard 的条带化日志方案
Northguard 采用**日志条带化(log striping)**的方式来均衡 I/O 负载。它将一条日志拆解成多个范围(Range)和段(Segment),每个段都可以有独立的副本集合。通过将日志细分,当新的日志写入时,这些细小的段会动态分布到不同的 Broker 上。正如 Northguard 文中描述的那样:“通过日志条带化,将日志拆成更小的块用于平衡 IO 负载……自然而然地,新的 Broker 会成为新创建段的副本,集群会自行平衡”。也就是说,即便某个时刻某台 Broker 比较繁忙,只要后续产生更多段,负载很快就会随着这些新段的分配而均匀下来,无需专门重平衡已有段。Northguard 的这种按需均衡设计彻底避免了长期热点:用户不再需要等待少量日志写完或手动迁移现有数据,系统会自动让负载“自己整理”。
当一个新的日志段被创建时(Range 中新增一个 Segment),它自动被分配到可用的 Broker。每个 Broker 只需持有其分配的段,随着时间推移,写负载会不断在全群分布开来,而不会长期集中在某几个节点上。
Pulsar 更精密的存储层
Pulsar 的存储层 BookKeeper 天生就具备均衡 I/O 的能力。BookKeeper 将每个主题/分区的数据写入称为 Ledger 的多个日志文件,这些 Ledger 均匀分布到不同的 Bookie(存储节点)上。每个 Ledger 自身通过多副本复制保障可靠性,读写操作互不干扰。同时,BookKeeper 设计成可以同时处理数千甚至更多的并发 Ledger,且使用独立的磁盘来隔离写入日志和数据文件。正因为如此,Pulsar 集群中不存在 Kafka 那样固定的写入热点;新的写流量可以自动分布到所有可用 Bookie,而任何单个节点都很难长期成为瓶颈。此外,Pulsar Broker 层的负载均衡器会定期将主题分配均匀到各 Broker,从而防止消费者访问热点。
Northguard 的日志条带化实现了自动负载均衡,使集群内的 I/O 均匀分布;Pulsar 则借助 BookKeeper 的并发 Ledger 机制和平衡策略,从根本上杜绝了固定热点问题。相比 Kafka,二者都不再需要额外的负载迁移工具,每次写入都会自动走向负载最轻的节点。
问题 4:故障恢复慢,需要人工干预
故障恢复方面,Kafka 也缺乏自动化机制。当某个 Broker 挂掉时,其上承载的分区副本会暂时不可用。通常需要运维人员手动触发分区重分配来恢复冗余,这个过程耗时较长。正如 LinkedIn 所描述:“由于分区是较重的复制单位,一旦某些副本失效,往往需要人工干预来恢复”。Kafka 在可用性和一致性之间往往要做折中,即为了保持可用性可能放弃强一致性保证。
Northguard 的自愈能力
Northguard 在元数据模型中内置了自我修复能力。每个 vnode 的 Raft 复制状态机都保存了其所管辖范围和段的完整状态。当 Northguard 检测到某个段的副本不完整时,对应的 vnode Leader 会主动发起额外的复制操作,将该段复制到其他 Broker 上以恢复冗余。Linkedin 文章也提到说:“协调器使用段状态来启动对欠副本段的复制,使得 Northguard 具备自愈能力”。这意味着,Northguard 能够在节点故障后自动补充丢失的副本,而无需人工介入。系统会监控所有段的健康状况,一旦发现异常就自动恢复,显著提高了可用性。
Pulsar 强大的故障恢复能力
Pulsar 的架构同样提供了强大的故障恢复能力。
首先,Pulsar Broker 是无状态的,出现故障时可以随时替换;Broker 挂掉并不会导致数据丢失,因为数据被存储在 BookKeeper 中。
其次,BookKeeper 使用多副本日志结构:如果某个 Bookie 节点出现故障,其他副本会接管读取请求,保持读一致性。BookKeeper 会自动监测副本丢失的 Ledger,并对其余留节点进行复制,从而确保每个 Ledger 的副本数达到预设值。
因此,当个别节点失效时,Pulsar 能迅速恢复冗余,不会像传统 Kafka 那样依赖人工干预。
Northguard 和 Pulsar 均内置了自动的故障恢复机制。与需要运维介入的 Kafka 不同,它们可以在后台自动修复丢失的副本,最大化系统可用性。对于用户而言,这意味着极少甚至无需手动重分配分区,系统会主动补齐冗余,业务恢复时间更短。
问题 5:运维复杂,可操作性差
由于前述各类问题的存在,Kafka 在大规模下的运维需要依赖大量外部工具和脚本。例如,LinkedIn 文中提到他们为了管理 100 多个集群,建立了一整套服务体系来平衡集群负载。常见的运维组件如 Cruise Control(用于负载再平衡)、MirrorMaker(用于跨集群复制)、自研脚本等,都被迫“长期陪跑”。
Kafka 其实缺乏开箱即用的弹性和自管理能力,最好的 Kafka 管理工具往往是闭源商业产品。这一切导致 Kafka 运维人员需要花费大量精力在配置、监控和调优上,而不是专注于业务功能。
Northguard 的自均衡
Northguard 在设计之初就强调“灯塔式运维”(lights-out operations),通过内置的自均衡和自愈特性来最大限度减少运维负担。LinkedIn 文中提到,Northguard 通过日志条带化(log striping)天然分散负载,并且新增 Broker 后会自动平衡,无需手动重新平衡或数据移动。换言之,Northguard 自带了负载均衡和故障修复功能,避免了依赖外部系统进行管理的需要。管理员只需配置策略和属性,系统就能自动执行大部分日常运维任务。
Pulsar 的略高的门槛后是简化的运维
Pulsar 也大幅简化了运维工作。Pulsar 集群提供自动负载均衡和拓扑感知功能:当集群增减节点时,系统自动重新分配主题,使负载在 Broker 和 Bookie 间均衡,新资源会立刻被利用。Pulsar 的自动负载均衡允许在 Broker 和 Bookie 增加时即时接收写流量,是无需人工重分配的。
另外,Pulsar 天生支持多租户和命名空间隔离,使不同团队之间可以共享同一个集群而互不干扰。这非常适合一个统一的大集群建设。加之 Broker 无状态设计,节点的上线下线变得非常简单,BookKeeper 轻量化的运维需求,让整体运维强度大大降低。对于 Pulsar 常规功能,初次接触的用户,往往是“越过山丘”,就是一片坦途。
对比 Kafka 的复杂运维生态,Northguard 和 Pulsar 都提供了更自动化的管理特性。Northguard 自带日志均衡和自愈机制,让其可以“少跑路”;Pulsar 则通过自动负载均衡、租户隔离、无状态 Broker 等设计,让运维工作变得直观而轻量。对于用户而言,这意味着更少的额外工具,更少的人力维护投入。
Pulsar 存算分离架构及其他优势
除了上面针对 Linkedin 提出问题的讨论,我们再来做个对 Apache Pulsar 存算分离架构的整体回顾。
Broker 专注于处理客户端请求和执行消息路由(计算层)
消息数据则被追加写入独立的 BookKeeper 存储节点(存储层)

上图示意了一个 Pulsar 集群的存算分离架构。多个 Broker 节点处理生产者和消费者请求,而 Apache ZooKeeper(或 etcd)则负责元数据管理,所有消息持久化到 BookKeeper 的多个 Bookie 中。
Pulsar 的分离架构还带来了其他更多的优势:
多租户与隔离: Pulsar 原生支持多租户,使用层次化的租户(tenant)和命名空间(namespace)概念来隔离不同组织或团队。管理员可以在不同租户和命名空间上设置访问控制和资源配额,避免不同应用互相干扰。Kafka 在这方面则需要自行设计配额或多个集群来隔离。
高可用与可扩展的存储: 由于消息存储在 BookKeeper,Pulsar 的扩展更灵活:可以独立地增加 Bookie 来扩容存储容量,也可以增加 Broker 来扩容计算能力,而两者之间互不影响。当 Bookie 失败时,BookKeeper 会自动恢复副本;而 Broker 失败时,只需将流量切换到其他 Broker 即可,因为它们不持有持久化数据。
性能优化: Pulsar 数据被拆分成多个 Ledger 并分布到多台机器上,Pulsar 能充分利用集群中的带宽和 I/O 资源。这些机制使得 Pulsar 在高吞吐、低延迟场景下拥有良好表现。
弹性与混合存储: Pulsar 支持自动故障恢复和分区弹性扩缩容,可与云存储集成做分层存储,进一步提升性能和成本效率。由于存算分离,Pulsar 很容易支持将旧数据归档到对象存储等冷存储,而不影响热数据的读写。这尤其对云上高昂成本的一次极大利好。
综上所述,Apache Pulsar 作为一个成熟的消息队列和流处理平台,不仅解决了 Northguard 提出的问题,还凭借其架构带来了多租户支持、自动运维、优化的性能和灵活的扩展能力等额外价值。而且这一切早已成熟稳定!
总结:直接选用 Pulsar
LinkedIn Northguard 所针对的问题核心其实就是 Kafka 单体架构的缺陷。通过对比分析可以看到,Northguard 和 Pulsar 在根本思路上都采用了数据与元数据的分布式切分、自平衡和自动恢复机制。然而,Apache Pulsar 早在多年前就引入了存算分离的架构设计,并在生产环境中广泛验证了其可行性和优势。对于大多数用户而言,与其重构 Kafka 或开发一套自己的解决方案,不如直接使用 Pulsar 来享受上述好处。Pulsar 作为一个开源系统,不仅体系成熟,还具有活跃的社区支持,它天然解决了扩容难、元数据瓶颈、热点调度、故障恢复慢和运维复杂等一系列问题。因此,我们建议对流数据规模化有需求的团队直接使用 Pulsar,以便快速获得存算分离架构带来的弹性和稳定性。
最后,在今天,再拿出中间件大师Jack Vanlightly 的传奇手绘《Kafka vs Pulsar - Rebalancing (Sketch)》,大家是不是更都有答案啦。

评论