Skip to content

消息队列的下一个十年:忘了 Kafka 吧

我一直在消息队列这个领域里面。

过去几年,看着 S3 存储、Kafka 兼容、存算分离这些方向一个接一个地出来,每个都觉得不错,但每个都觉得差了点什么。说不上来差在哪——工程质量没问题,方向也合理,就是看完之后没有那种"对,这就是未来"的感觉。

最近想明白了。差的不是实现,差的是思考的起点。我们对"消息"这件事的理解,太窄了。

不是大家想不到,而是场景还没来。场景没来,也没法想。现在场景来了。


Kafka 定义了我们的思考方式

2011 年 Kafka 从 LinkedIn 开源,解决的是一个非常具体的问题:大规模日志收集和实时数据管道。Append only log、多副本、partition、consumer group——这套模型完美匹配了大数据时代的核心需求:海量数据从 A 搬到 B,不丢,不乱,够快。

然后这套模型赢了。赢得太彻底了。

它不只是一个产品的设计选择,而是变成了整个行业对"消息系统应该长什么样"的默认认知。今天你跟任何一个工程师聊消息队列,他脑子里浮现的第一个画面大概率是:topic、partition、offset、consumer group。

这件事本身没有问题。Kafka 的成功是实至名归的,它确实在自己的场景里做到了极致。问题在于,当一个模型赢得太彻底,它会固化成一种思考方式,让所有人——包括后来的竞争者——都在同一个框架里打转。


S3 和数据湖叙事:在正确的框架里走到了尽头?

过去几年,消息队列领域最热的方向是什么?S3 存储。

AutoMQ 把 Kafka 的存储层搬到对象存储上,成本大幅下降。WarpStream 更激进,直接把数据写到 S3,连本地磁盘都不要了。Confluent 自己也在做 Freight,走的是同一条路。StreamNative 做 Pulsar + Iceberg 融合,把消息数据直接落到 Lakehouse 里,省掉中间搬运的环节——换了个姿势,但本质上还是在优化数据从 A 到 B 的效率和成本。Redpanda 用 C++ 重写 Kafka,把性能做到极致。Pulsar 早年就做了存算分离,BookKeeper + tiered storage。

这些产品的工程质量都很高,解决的问题也是真实的。但如果你退后一步看,会发现一个有意思的现象:所有人都在同一个假设下竞争,只是在不同的维度上优化。

Redpanda 优化的是性能——同样的模型,用 C++ 做得更快。AutoMQ 优化的是成本——同样的模型,用 S3 做得更便宜。Pulsar 优化的是弹性——同样的模型,存算分离做得更灵活。Confluent 优化的是生态——同样的模型,上下游集成做得更完整。

没有人质疑模型本身。

为什么大家都聚焦 S3?因为如果你接受 Kafka 的心智模型——消息就是 append only log,核心能力就是吞吐和可靠性——那优化的路径确实只剩下存储成本。本地磁盘贵,S3 便宜,逻辑闭环。

但 S3 叙事的天花板也在这里:它只能讲成本和延迟的故事。

"我们比 Kafka 便宜 80%"——不错。但代价是尾延迟从 50ms 涨到了 100ms。便宜了,但也慢了。你听完之后总觉得缺了点什么。缺的是什么?缺的是对未来的回答。S3 的叙事永远在成本和延迟之间做跷跷板,便宜 80% 解决的是今天的问题,它不回答明天的通信需求长什么样。

这不是说 S3 方向错了。在 Kafka 的评价体系里,这条路走得非常正确。但正因为它走得太正确,反而暴露了一个更深的问题:当你在一个固定的模型里把成本和性能都优化到极致之后,下一步去哪?

答案是:在这个模型里,已经没有下一步了。


卖铁的逻辑

还有一层更深的锁定。

Kafka 的商业模型,本质上是卖资源。流量越大,partition 越多,broker 越多,磁盘越多,收入越多。Confluent Cloud 按吞吐量和存储量计费。Redpanda 也是。AutoMQ 用 S3 把单价降下来了,但商业逻辑没变——用户量大了,用的多了,你就赚钱了。

这就是"卖铁"逻辑:你的收入跟用户消耗的物理资源成正比。量大,流量大,有钱赚。

在过去十年的互联网场景里,这个逻辑完全成立。大厂的日志量、交易流水、实时数仓,数据量只会越来越大,Kafka 的收入跟互联网的增长曲线高度一致。

但这个逻辑把整个行业的注意力锁在了"量"上。大家都在问:怎么处理更大的吞吐?怎么存储更多的数据?怎么降低单 GB 的成本?因为这些问题直接对应收入。

结果是:我们在不断优化搬运数据的效率,但越来越少有人去想,我们到底在搬运什么,为谁搬运,通信的本质需求到底是什么。

我觉得这不是错。在"量"的时代,这些都是正确的事。但我觉得这不是未来。


通信不只有一种形态

如果你跳出 Kafka 的心智模型,重新看"通信"这件事,会发现它的形态远比 append only log 丰富。

邮箱。 我给你发一条消息,你不在线,消息等着,你上线了自己来取。取完可以删,也可以留。这是最古老的异步通信模型——email 就是这样。但在 Kafka 的世界里,你要实现这个语义,得为每个人创建一个 topic,配置 retention,管理 offset,10 个人可以,10 万个人就崩了。

广播。 我喊一嗓子,谁听到谁处理,我不关心谁听到了。不需要持久化,不需要确认,不需要回溯。MQTT 的 QoS 0 就是这个语义,NATS 的 core pub/sub 也是。但如果你只有 Kafka,你得创建 topic,配 consumer group,即使消息的生命周期只有几秒钟。

最新值。 我只关心某个状态的当前值,历史值对我没意义。传感器温度、设备在线状态、服务健康度——要的是 key-value 的覆盖写,不是 append only 的追加写。Kafka 有 compacted topic 来近似实现,但这是在 log 模型上打的补丁。

请求-响应。 我发一个请求,等你回一个响应,超时就重试。NATS 原生支持 request-reply,AMQP 可以用 reply-to 实现。Kafka 天生不擅长这个——它是为异步流设计的,不是为同步交互设计的。

临时通道。 两个参与者临时建立一条通信链路,用完即弃。不需要持久化基础设施,需要的是极低的创建成本和自动的生命周期管理。

这些通信形态一直存在,只是在 Kafka 统治的叙事里被边缘化了。


AMQP 和 NATS:被低估的两条路

值得回头看看两个在 Kafka 光环下被低估的协议。

AMQP 在 2006 年做对了一件事:把路由和存储分开。Exchange 负责路由逻辑——direct、fanout、topic、headers,每种都是独立的路由策略。Queue 负责存储和消费。这个分层的价值在于路由策略可以灵活组合,同一条消息根据不同规则投递到不同地方,不需要复制多份。

RabbitMQ 在性能上输给了 Kafka,但在模型的灵活性上丰富得多。可惜 Erlang 的性能天花板和单机架构的局限性,让很多人把 AMQP 模型的价值和 RabbitMQ 的实现局限混为一谈了。协议思想没问题,是实现没跟上。

NATS 走了另一条路:极简。Core NATS 就是 pub/sub + request/reply,没有持久化,消息发完就没了。在 Kafka 的评价体系里简直是"玩具"——消息不持久化?那叫什么消息队列?

但 NATS 想解决的问题本来就不是数据管道,而是服务间通信。它要的是极低延迟、极简协议、极低资源占用。后来加的 JetStream 补上了持久化,但 NATS 的灵魂不在 JetStream 里,在 core 的轻量和直接里。

这两个协议代表的方向——灵活路由和极简通信——在 Kafka 主导的十年里没有得到应有的关注。但场景正在把它们重新推到台前。


Agent 时代:场景变了,模型得跟着变

黄东旭最近写了一篇关于 AI Agent 基础软件的文章,里面有一个数据:TiDB Cloud 每天新创建的集群里,超过 90% 是 AI Agent 直接创建的。

这不是预测,是正在发生的事。

Agent 使用基础设施的方式跟人类开发者完全不同。它是临时的——可能只活几秒。它是海量的——一个编排系统同时跑成千上万个 Agent。它是自主的——不按预设的 topic 结构投递消息,需要动态建立通信关系。

把这些特征放到 Kafka 的模型里,每一条都是摩擦。为一个只活 5 秒的 Agent 创建一个 topic,配 3 副本,分配 partition——它死了你还得清理。10 个 Agent 无所谓,10 万个就是系统性的负担。

更根本的变化是消息的"价值密度"。在数据管道里,每条消息都是业务事件,丢了就是数据丢失。在 Agent 通信里,大量消息是临时的、可重试的、一次性的。Agent 可以重发,可以换一个 Agent 重试,可以换一种策略重来。

高可靠、多副本、零丢失——上一个时代的核心指标,在这个场景里变成了不必要的成本。

不是说可靠性不重要了,而是:不是所有通信都需要同一个级别的可靠性。选择权比绝对保障更重要。

有些消息需要三副本持久化——关键事件日志、审计记录。有些消息只需要在内存里停留几秒——Agent 之间的协调信号。有些消息需要临时持久化——等对方上线就交付,之后自动清理。一个好的通信基础设施应该让用户按需选择,而不是把所有消息都按最高规格处理。


底层必须是原子的

到这里,可以聊一个更底层的判断了。

过去十年的消息系统是"大模型"思维——一个 append only log 解决所有问题。场景不匹配的地方靠配置和参数适配。S3 存储方向也是在这个大模型上做外科手术——把底下的磁盘换掉,上面的东西不变。

我认为下一个十年的方向是反过来的:底层必须是原子的、细粒度的,上层按场景组合封装。

什么叫原子的?

存储是原子的——一条消息的存储可以是内存、本地磁盘、或者对象存储,由场景决定,不由系统强制。路由是原子的——点对点投递、扇出广播、规则匹配,每种路由逻辑独立存在,按需组合。生命周期是原子的——消息的 TTL、清理策略、持久化级别,每条消息可以不一样。租户是原子的——创建一个通信实体的成本趋近于零,销毁也是。

上层怎么组合?

需要 Kafka 语义——用持久化存储 + 有序路由 + offset 管理组合出来。需要邮箱语义——用临时持久化 + 点对点路由 + TTL 组合出来。需要广播语义——用内存路由 + 订阅匹配组合出来。需要请求响应语义——用临时通道 + 超时机制组合出来。

不是一个模型打天下,是底层足够细,上层按需拼。

这和数据库领域的演进是同一个方向:从"一个 Oracle 解决所有问题",到 Redis 做缓存、Elasticsearch 做搜索、ClickHouse 做分析、TiDB 做 HTAP。不同的是,消息领域更好的路径可能不是为每个场景造一个独立产品,而是用一套足够原子的底层能力去组合出不同场景的解法。


评价体系也要变

如果底层假设变了,评价体系得跟着变。

过去十年,消息系统比的是:每秒多少条消息?端到端延迟多少毫秒?多少个 9 的可用性?这些指标衡量的是"量"的能力——你能搬多少数据。

下一个十年,可能需要加上另一组指标:系统能同时支撑多少个独立的通信实体?创建和销毁一个通信实体的成本是多少?从"三副本持久化"切换到"纯内存过一下"需要改多少东西?系统能在不停机的情况下同时服务多少种通信模式?

前一组衡量"量",后一组衡量"多"。

我的判断是:下一代消息基础设施的核心竞争力,在"多",不在"量"。

"量"的问题已经被 Kafka 和它的后继者们解决得足够好了。在 append only log + 多副本这条路上,S3 存储可能是最后一块大的优化空间,之后的边际收益会越来越小。

真正的增量空间在"多"——在那些 Kafka 模型覆盖不到的、正在快速增长的、今天还没有好答案的通信场景里。


最后

这篇文章没有给出具体的技术方案,因为我想说的不是"应该怎么做",而是"应该怎么想"。

消息队列这个领域过去十年的进步是巨大的,Kafka 生态的成熟度令人敬畏。S3 存储方向解决的也是真实的问题。但当场景发生根本性变化的时候,上一代的成功经验往往是下一代的认知枷锁。

Append only log 不是通信的全部。高吞吐、高可靠、低延迟不是唯一重要的指标。把存储成本优化到极致也不等于找到了未来。

底层越原子,上层越自由。

想清楚这些,比选择用哪个产品重要得多。

🎉 既然都登录了 GitHub,不如顺手给我们点个 Star 吧!⭐ 你的支持是我们最大的动力 🚀