[转]Kafka 解决了什么问题?
作者:Cv大法代码酱
链接:https://www.zhihu.com/question/53331259/answer/1970978313083258152
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
都快2026年了,还把Kafka当成一个简单的消息队列,跟Redis的Pub/Sub放一起比,这本身就是对Kafka最大的误解,也是对你司技术架构最大的不负责任。
Redis的Pub/Sub是啥?是个功能,是个锦上添花的东西,它本质上还是那个快得飞起的内存数据库。而Kafka是啥?它是一个体系,一个生态,一套解决现代数据问题的世界观和方法论。它压根就不是一个量级的东西。
你问Kafka解决了什么问题?我用最直接的大白话给你讲清楚,保证你听完就能跟面试官或者你老板掰扯。
一、Kafka解决的,根本不是“发消息”这点破事,而是“数据流”的有序和可追溯
咱们先从你提到的Redis Pub/Sub说起。这哥们儿的逻辑很简单,我,一个发布者,往一个channel里喊一嗓子,谁订阅了这个channel,谁就能听到。听到了就听到了,听不到,比如你当时掉线了或者服务崩了,那这嗓子就随风飘散了,没了。
这叫“Fire-and-Forget”,即发即忘。这种模式在某些场景下特别好使,比如:
- 一个简单的实时通知,告诉前端页面“哎,你这有个新消息”。
- 几个微服务之间临时的信令同步,不那么重要的那种。
- 游戏的房间状态广播。
它的优点是快,延迟极低,因为数据基本不落地,直接在内存里转发。但它的命门也就在这:数据不负责,不持久化,不可靠,一丢就是真丢了。 你让它去扛一个电商大促的订单消息?你让它去接一个金融App的用户交易流水?别闹了,那是自寻死路。丢一个订单,客服电话能被打爆;丢一条交易,公司第二天就得上新闻。
所以,Kafka要解决的第一个,也是最核心的问题,就不是“通知”,而是“记录”。
Kafka的底层设计,你别管那些Topic、Partition、Broker这些名词,你就记住四个字:分布式日志(Distributed Log)。啥叫日志?就是记下来的东西,按顺序写的,写上了就不会丢,你想看随时能翻回来看。
想象一下,你所有的数据,不管是用户的点击行为、后端服务的调用日志、数据库的变更记录(CDC),还是IoT设备上传的传感器数据,都像一条源源不断的河流,Kafka就是这条河的河床。数据流进来,Kafka就按顺序把它们一段一段地记录在硬盘上。
这个“记录在硬盘上”,就是它跟Redis Pub/Sub的根本性区别。这意味着:
- 数据的持久化和可靠性。 数据写进Kafka(只要配置得当,比如ISR机制),基本上就不会丢。你的消费端程序崩了?没事,重启一下,从上次消费到的位置继续读就行了。数据中心断电了?没事,Kafka集群有副本机制,另一台机器上还有你的数据。这种可靠性,是构建严肃数据系统的基石。
- 数据的可回溯性(Time Travel)。 这是Kafka的王炸功能,也是它碾压传统消息队列(比如早期的RabbitMQ、ActiveMQ)的地方。因为数据是持久化日志,所以你可以让一个消费者“回到过去”。给你讲个我亲身经历的糟心事。
大概是19年吧,我当时带一个推荐算法团队,我们的一个核心业务就是根据用户的实时行为流,用Flink去跑一个在线学习模型,实时更新推荐结果。数据流大概是这样:APP前端埋点 -> Nginx日志 -> Logstash -> Kafka -> Flink -> Redis/HBase(存模型特征)。有一次,一个新来的小伙子上线了一个新版的特征提取逻辑,代码里有个bug,导致接下来6个小时所有用户的行为特征全都提错了,线上推荐系统的CTR(点击率)直接腰斩。当时PM和运营的脸都绿了,老板在群里已经开始@人了。怎么办?如果是Redis Pub/Sub或者传统的“阅后即焚”消息队列,那这6个小时的原始用户行为数据早就没了,我们只能干瞪眼,等着第二天被吊起來打。但我们用的是Kafka。当时我让那个小伙子别慌,先立刻回滚代码,然后干了这么个“骚操作”:
- 在Flink里重新部署上一个正确的代码版本。
- 修改消费组的Offset,直接重置到6个小时前出问题那个时间点的位置。
- 重新启动Flink Job。
接下来发生的事情就很魔幻了。Flink开始疯狂地消费Kafka里那6个小时的“历史数据”,就好像时间倒流了一样。它用正确的逻辑把所有旧数据重新计算了一遍,把错误的特征全部覆盖掉。大概花了半个多小时,整个系统就恢复到了事故发生前的状态。除了那半小时的延迟,6个小时的错误数据被完美修复,业务损失降到最低。
这就是Kafka的可回溯性带来的价值。它不仅仅是一个消息管道,它是一个可以让你“反悔”的数据总线。 它是你数据团队的“后悔药”。有了这个能力,你可以做很多事情:A/B测试新算法、修复Bug、做数据复盘、训练模型……
所以,你再看,Kafka解决的是“发消息”吗?不,它解决的是数据流的存储、可靠传输和事后追溯的问题。这是一个数据 infrastructure(基础设施)层面的问题。
如果你想把这个核心理念彻底搞懂,我不多推荐,就一本神书,Martin Kleppmann的《数据密集型应用设计》(Designing Data-Intensive Applications),行业黑话叫DDIA。这本书第七章和第十一章把日志这个概念讲得透透的,看完你就明白为啥Kafka是这么设计的了。
最近数分名著DDIA有了第二版,还有中文版了。

不过说实话。可能很多人连第一版都还没读明白,但是这也不能怪他们。因为因为DDIA就是很难,对很多刚入门或者转行到分布式系统、数据库、大数据领域的朋友来说,可能只能理解 20%-30% 的内容。要真正全部消化这本书,需要至少 1-2 年在大厂参与大型分布式系统工作或者长期维护复杂系统的实战经验才能跟上作者的思路。
所以推荐一个配套的DDIA 逐章带读,作者基于英语原版,结合自己丰富的工作经验,做了大量扩展和细致说明。可读性起码提高80%。推荐新手同学搭配第二版和解读一起读。
二、Kafka解决的,是系统间的“极限解耦”和“吞吐量”的矛盾
传统的系统间调用,要么是RPC(比如Dubbo、gRPC),要么是HTTP API。这种方式简单直接,但耦合度太高。A服务调B服务,B一挂,A就跟着报错。如果A要调B、C、D三个服务,那A的代码里就得写三次调用逻辑。哪天加个E服务,A还得改代码。这在复杂的微服务架构里就是灾难。
消息队列能解耦,这谁都知道。A把消息扔队列里就完事了,B、C、D、E谁想用自己去拿。
但问题来了,如果这个数据流非常庞大怎么办?
比如,我们现在搞的AIGC业务,用户生成一张图片,背后可能涉及到十几个模型的串聯调用和数据处理。用户行为日志、模型推理日志、内容审核日志、CDN分发日志……这些数据洪流,峰值时候的QPS(每秒查询率)可能达到几十万甚至上百万。
你用RabbitMQ这种传统AMQP模型的消息队列试试?它会告诉你什么叫力不从心。这类队列的瓶颈在于Broker(中间人)的复杂路由和消息管理。
而Redis Pub/Sub呢?它快是快,但它没有缓冲能力,发布者有多快,消费者就得知多快地消费,否则消息就堆积然后丢失了。发布端的流量洪峰会直接打垮消费端。
Kafka在这里,扮演了一个至关重要的角色:巨型缓冲池和削峰填谷器。
它的设计哲学就是极致的顺序读写。数据来了,直接往Partition文件的末尾追加,这是硬盘最高效的写入方式。消费者来读,也是从某个Offset位置开始顺序地往后读,同样是最高效的读取方式。没有复杂的消息确认和路由逻辑。Broker本身成了无状态的,状态(消费到哪了)由消费者自己记录。
这种朴实无华的设计,带来了恐怖的高吞吐量。单机Kafka节点的写入TPS(每秒事务数)就能轻松达到几十万甚至上百万。而且它可以水平扩展,你觉得不够快?加机器就行了。
这就完美解决了“解耦”和“吞吐量”的矛盾。
再给你个具体的场景,我们内部的数据总线就是这么干的。
我们公司所有业务线的核心数据,比如订单数据、支付数据、用户行为数据,都会产生一条标准的Canal或者Debezium捕获的数据库binlog消息,发到统一的Kafka集群里。
然后下游就炸开锅了:
- 实时数仓团队,会订阅这些数据流,用Flink SQL清洗、聚合后写入ClickHouse或者Doris,用于实时的BI报表和 Ad-hoc查询。
- 搜索团队,会订阅商品和内容相关的变更数据,实时更新Elasticsearch索引,保证搜索结果的 freshness。
- 风控团队,会订阅支付和用户行为数据,用Storm或者Flink跑实时风控规则,发现异常交易立刻告警或拦截。
- 算法团队,会订阅所有他们感兴趣的数据,用来更新推荐模型、用户画像、CTR预估模型。
- Archive团队,会用一个低优先级的消费者,把Kafka里所有的数据T+1地dump到HDFS或者对象存储(比如S3、OSS)里,做离线数仓的备份和模型训练。
你看,一个上游数据源,N个下游消费方。大家各取所需,互不干扰。上游的DBA半夜做了个表结构变更,只要不影响核心字段,下游大部分团队根本无感。搜索团队的ES集群崩了,没关系,修好了从Kafka里把数据重新消费一遍就行。实时数仓的Flink Job写了个bug,没事,回滚代码,重置Offset,再来一遍。
这就是Kafka作为数据总线(Data Bus)的威力。它让整个公司的数据流动起来,并且是有序、可靠、可追溯的。它成了整个数据驱动架构的心脏。
三,Kafka已经不是一个“组件”,而是一个“平台”
如果你对Kafka的认知还停留在上面两点,那你可能还活在2020年。
这几年,Kafka的生态已经進化到让人害怕的地步了。以Confluent(Kafka商业化的公司,创始人就是Kafka的作者)为首的社区,正在把它从一个数据管道,硬生生打造成一个流处理平台(Streaming Platform)。
这里必须提两个东西:Kafka Streams 和 ksqlDB。
Kafka Streams是一个Java库。它让你能够用写普通Java应用的方式,去处理Kafka里的数据流。比如你可以直接从一个Topic读数据,做一些map, filter, join, window(开窗)之类的操作,然后把结果写回另一个Topic。整个过程,它帮你处理好了状态管理、容错、分布式协调这些脏活累活。这意味着,对于一些中轻度的流处理任务,你根本不需要再单独搭建一套重量级的Spark或Flink集群了。你的应用本身,就是一个流处理器。
而ksqlDB就更狠了。它直接把Kafka变成了“流式数据库”。你可以用类似于SQL的语法,去查询、过滤、聚合Kafka里动态的数据流。
比如,你可以直接敲这么一行命令:CREATE TABLE user_clicks_per_minute AS SELECT user_id, COUNT(*) FROM clicks WINDOW TUMBLING (SIZE 1 MINUTE) GROUP BY user_id;
就这么一行,你就创建了一个实时 continuously updating(持续更新)的表,这个表里存的是每分钟每个用户的点击次数。你可以直接SELECT * FROM user_clicks_per_minute WHERE user_id = '123'; 来查询结果。
这个能力意味着什么?意味着数据分析和业务开发的门槛被大大降低了。以前需要数据工程师吭哧吭哧写半天Flink代码才能实现的实时统计报表,现在一个懂SQL的后端开发或者数据分析师就能搞定。
所以你看到了吗?Kafka + Kafka Connect (负责连接各种数据源) + Kafka Streams + ksqlDB,这一整套东西,已经形成了一个闭环。它覆盖了数据集成、数据存储、数据处理和数据查询的全链路。它在试图定义下一代数据架构的范式:以流(Stream)为核心,而不是以批(Batch)为核心。
如果你想跟上这个趋势,我强烈建议你去看看Confluent的官方博客和开发者网站(http://developer.confluent.io)。那里有最前沿的理念和最佳实践,比国内大部分二手博客不知道高到哪里去了。
四、那我到底什么时候用Kafka,什么时候用Redis?
讲了这么多,我们回到最初的问题,做个简单粗暴的总结。
你应该优先考虑Kafka的场景:
- 日志收集与分析:所有需要收集分析用户行为、系统日志、应用指标的地方。这是Kafka的老本行。
- 数据总线/事件驱动架构:作为微服务架构的核心,解耦各个服务,让数据在不同业务单元间可靠流转。
- 实时数据管道:连接各种实时计算引擎(Flink, Spark Streaming)和下游系统(DB, Search Index, Data Warehouse),构建ETL/ELT pipeline。
4e 数据持久化与可回溯:任何对数据可靠性要求高,且可能需要“后悔”(重放数据)的场景,比如金融交易、订单处理。 - 高吞吐量数据缓冲:当上游生产数据的速度远超下游消费能力时,用来做削峰填谷的巨型缓冲区。
你可以使用Redis Pub/Sub的场景:
- 实时但“不重要”的通知:比如网页消息推送、IM聊天里的“对方正在输入...”这种。
- 简单的信令与协调:比如分布式系统里几个节点间需要一个快速的广播通知机制。
3e 低延迟、小数据量的广播:数据量不大,但对延迟要求极其苛刻,并且可以容忍偶尔的消息丢失。 - 作为现有Redis应用的一个附属功能:你已经在用Redis了,顺手用一下它的Pub/Sub实现个简单的发布订阅,不想引入新的技术栈。
说白了,这是一道架构哲学题,而不是简单的技术选型题。
- 你的系统是围绕“状态”构建的,还是围绕“事件”构建的?
- 你的数据是“一次性”的,还是需要“反复咀嚼”的?
- 你的架构追求的是“极致的低延迟”,还是“长期的可扩展性和可靠性”?
想清楚这几个问题,答案自然就出来了。
我话放这,未来五年,但凡是想做数据驱动、想搞实时智能的公司,你的技术栈里都绕不开Kafka这一套体系。它可能不是在所有场景下都是最优解,但它一定是那个你必须 understanding and mastering(理解和掌握)的“标准答案”。
在这里也给想入门大数据行业的新人或者想进一步在这个领域深耕的小伙伴奉上一套优质的学习资源。涵盖了数据分析、大数据基础、大数据架构、数据仓库、数据治理、bat真实案例,科研绘图与工具、大厂面试真题附含答案以及简历模板等众多干货。点击获取即可⬇
别再纠结它和Redis Pub/Sub是不是功能重叠了。这就好像在问,你家的总水管和我厨房的水龙头是不是功能重叠一样。它们都在流水,但一个决定了你整个屋子的用水上限和稳定性,另一个只决定了你洗菜方不方便。
格局,要打开。