Apache Kafka — 分布式流处理平台
是什么
Kafka 是一个持久化日志 + 发布订阅系统,2010 年 LinkedIn 开发并在 2011 年开源给 Apache 基金会。一个集群每秒能处理百万条消息,被 LinkedIn、Uber、Netflix、Twitter 等大型实时数据系统当成数据管道的中枢。
日常类比:就像超市的传送带——商家(producer)把商品放到传送带上,多个收银员(consumer)按顺序从传送带上取货。传送带自己记录每件商品的位置(offset),收银员只要告诉传送带”我取到了第 42 号商品”,下次就能从第 43 号继续取。
你写一个最简单的发消息:
bin/kafka-console-producer --topic events --bootstrap-server localhost:9092> hello kafka另一个进程订阅同一个 topic:
bin/kafka-console-consumer --topic events --from-beginning --bootstrap-server localhost:9092hello kafka发送方不需要知道接收方在哪、是谁、什么时候来——这就是发布订阅最基础的解耦能力。
为什么重要
不理解 Kafka 的设计哲学,下面这些事都没法解释:
- 为什么 LinkedIn / Uber / Netflix / Twitter 这种”每秒百万事件”的公司,数据管道几乎都是 Kafka
- 为什么 Kafka Streams + ksqlDB 让流处理像写 SQL 一样——
SELECT FROM clicks WHERE user='alice'直接出结果 - 为什么 Kafka Connect 一千多个连接器(MySQL / Elasticsearch / S3 / 任何系统),让”任何系统都能进出”
- 为什么 Kafka 在 2020 年后逐渐替代 RabbitMQ / ActiveMQ,成为新一代消息队列标准
简单说:这是过去 10 年大数据基础设施最重要的开源项目之一,是”实时数据”这个范式的地基。
核心要点
Kafka 的核心模型可以拆成 三层:
-
Topic + Partition:一个 topic 是一类消息的分类(如
user-clicks、order-events)。一个 topic 切成多个 partition,每个 partition 是一个独立的有序日志,可以并行写入和读取——这是 Kafka 横向扩展的根本。 -
Producer + Consumer Group:producer 把消息发到 topic,Kafka 决定写入哪个 partition(按 key hash 或轮询)。consumer 订阅 topic 时加入一个 consumer group,同 group 内的 consumer 自动分摊 partition——4 个 partition、2 个 consumer,每人吃 2 个;3 个 consumer,每人 1-2 个。
-
Offset + 持久化:每条消息在 partition 内有一个递增编号叫 offset。Kafka 把消息持久化到磁盘(默认保留 7 天),consumer 自己记录”我消费到 offset 多少了”。所以消费者挂了重启也能从断点继续,不会丢消息。
简单说:topic 是邮筒,partition 是邮筒里的并行格子,consumer group 是分工取信的一组邮差,offset 是邮差的进度书签。
实践案例
案例 1:Docker 起一个 Kafka 集群
最快上手的方式是用 Confluent 的官方镜像:
services: kafka: image: confluentinc/cp-kafka:7.5.0 ports: - "9092:9092" environment: KAFKA_NODE_ID: 1 KAFKA_PROCESS_ROLES: 'broker,controller' KAFKA_LISTENERS: 'PLAINTEXT://:9092,CONTROLLER://:9093'docker compose up -d注意这里没有 ZooKeeper——Kafka 3.3 之后用 KRaft 模式,broker 自己管元数据。
案例 2:发消息和收消息
# 创建 topicbin/kafka-topics --create --topic events --partitions 3 \ --bootstrap-server localhost:9092
# 发消息bin/kafka-console-producer --topic events --bootstrap-server localhost:9092> {"user": "alice", "action": "click"}
# 收消息(从头开始读)bin/kafka-console-consumer --topic events --from-beginning \ --bootstrap-server localhost:9092--from-beginning 是 Kafka 的杀手锏——消息已经持久化在磁盘上,新加的 consumer 可以从最早的消息回放。
案例 3:Consumer Group 的水平扩展
启动两个 consumer 都用 group analytics:
# 终端 1bin/kafka-console-consumer --topic events --group analytics \ --bootstrap-server localhost:9092
# 终端 2(不同终端)bin/kafka-console-consumer --topic events --group analytics \ --bootstrap-server localhost:9092Kafka 会自动把 3 个 partition 分给两个 consumer(一个吃 2 个,另一个吃 1 个)。再加一个 consumer,每人正好 1 个。这就是流处理水平扩展的工程实现。
踩过的坑
-
Partition 数预估错:partition 数是 topic 创建时定的,事后只能加不能减。设少了无法横向扩 consumer(consumer 数 ≤ partition 数);设多了 broker 元数据爆炸(每个 partition 占内存和文件句柄)。经验值:每 broker 不超过 2000-4000 partition。
-
Consumer Rebalancing 期间消息处理停顿:consumer 加入或退出 group 时会触发 rebalance,所有 consumer 暂停消费几秒到几十秒。Kafka 2.4 引入
cooperative-sticky分配策略缓解了这个问题——只重分配必要的 partition,不全量打散。 -
Exactly-once 语义复杂:默认是 at-least-once(可能重复)。要做到 exactly-once 必须开启 idempotent producer + transactional consumer,配置一堆参数(
enable.idempotence、transactional.id、isolation.level=read_committed),且只在 Kafka 内部端到端有效——出了 Kafka 还是要业务层去重。 -
监控指标多到爆炸:consumer lag(落后多少消息)/ throughput(吞吐)/ disk usage / GC 时间 / network IO ——任何一个炸了集群都可能挂。生产环境必须上 Confluent Control Center 或 LinkedIn 开源的 Burrow,光看 broker 自己的 JMX 不够。
适用 vs 不适用场景
适用:
- 大型实时数据管道(用户行为、日志聚合、CDC 数据库变更捕获)
- 微服务间事件驱动架构(订单事件 → 库存 + 物流 + 通知 多个下游)
- 流处理(Kafka Streams / Flink / Spark Streaming 的输入源)
- 需要消息持久化和回放的场景(消息保留 N 天,新业务上线可以从头消费)
不适用:
- 低延迟点对点通信(毫秒级 RPC 用 gRPC 更合适)
- 小规模消息队列(几千 QPS 用 RabbitMQ / Redis Stream 更轻)
- 严格 FIFO 跨多 partition(Kafka 只保证单 partition 内有序)
- 复杂路由规则(topic exchange、header routing 这种用 RabbitMQ)
历史小故事(可跳过)
- 2010 年:LinkedIn 工程师 Jay Kreps 主导开发,名字来源于作家 Franz Kafka——“我喜欢一个写作系统命名的项目,所以叫了 Kafka”。
- 2011 年:开源给 Apache 基金会,进入孵化器。
- 2014 年:Jay Kreps 等核心团队从 LinkedIn 离职创立 Confluent,主导 Kafka 商业化。
- 2017 年:Kafka Streams 发布,第一个内嵌在 Kafka 里的流处理库(不需要 Spark/Flink)。
- 2020 年:KIP-500 提案,开始移除对 ZooKeeper 的依赖(KRaft 模式自管元数据)。
- 2024 年:Kafka 3.7 起 KRaft 默认开启,ZooKeeper 模式标记为废弃;Tiered Storage GA(冷数据下沉到 S3,降低存储成本)。
15 年从 LinkedIn 内部工具到全球数据基础设施标配。
学到什么
- 持久化日志是个好抽象——把”消息队列”和”分布式日志”统一了,副作用变成事实记录
- Partition + Consumer Group 是横向扩展的范式——任何流处理系统都在重新发明这个模型
- 零拷贝 + 顺序写磁盘——Kafka 性能秘诀不是内存而是顺序 IO 比随机内存还快
- 生态比单点功能重要——Kafka Connect 的 1000+ 连接器让它成为”任何系统的胶水层”
延伸阅读
- 官方文档:Apache Kafka Documentation(先看 “Introduction” 和 “Quick Start”)
- 经典文章:The Log: What every software engineer should know(Jay Kreps 写的,理解 Kafka 设计哲学的必读)
- 视频:Confluent Developer — Apache Kafka 101(10 节短视频从零到上手)
- 实战书:Kafka: The Definitive Guide, 2nd Edition(O’Reilly 出版,Confluent 工程师写)
- redis —— Redis Stream 是 Kafka 的轻量替代品,理解差异有助于选型
关联
- redis —— Redis 也能做消息队列(list / pub-sub / stream),但持久化和扩展性远弱于 Kafka