Chapter 01

Kafka 架构与核心概念

从消息队列到流处理平台的演进——理解 Kafka 设计哲学与工业级性能的根源

什么是 Kafka

Apache Kafka 是一个分布式事件流平台,最初由 LinkedIn 工程师 Jay Kreps 等人于 2010 年设计,2011 年开源并捐赠给 Apache 基金会。其名字来自作家 Franz Kafka——因为这个系统被设计为"优化写入",正如卡夫卡的写作风格一般充满流动感。

Kafka 的定位经历了三个阶段的演进:

阶段定位核心能力
第一代(2011)消息队列(MQ)解耦生产者与消费者,异步通信
第二代(2014)发布/订阅系统多消费者组并发消费,消息持久化
第三代(2017+)事件流平台Streams 流处理、Connect 集成、Exactly-Once 语义

Kafka vs 传统 MQ:传统消息队列(如 RabbitMQ)的消息被消费后即删除。Kafka 的消息按配置的时间/大小保留(默认 7 天),任何消费者组都可以从任意 Offset 重新消费——这使得 Kafka 更像一个可重放的事件日志,而非一次性管道。

核心架构组件

Kafka 集群整体架构 Kafka Cluster ┌──────────────────────────────────────────────────────────────┐ │ │ │ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │ │ │ Broker 1 │ │ Broker 2 │ │ Broker 3 │ │ │ │ ┌──────────┐ │ │ ┌──────────┐ │ │ ┌──────────┐ │ │ │ │ │orders P0 │ │ │ │orders P1 │ │ │ │orders P2 │ │ │ │ │ │(Leader) │ │ │ │(Leader) │ │ │ │(Leader) │ │ │ │ │ └──────────┘ │ │ └──────────┘ │ │ └──────────┘ │ │ │ │ ┌──────────┐ │ │ ┌──────────┐ │ │ ┌──────────┐ │ │ │ │ │orders P1 │ │ │ │orders P2 │ │ │ │orders P0 │ │ │ │ │ │(Follower)│ │ │ │(Follower)│ │ │ │(Follower)│ │ │ │ │ └──────────┘ │ │ └──────────┘ │ │ └──────────┘ │ │ │ └──────────────┘ └──────────────┘ └──────────────┘ │ │ │ └──────────────────────────────────────────────────────────────┘ ↑ 写入 ↓ 读取 ┌─────────────┐ ┌───────────────────┐ │ Producer │ │ Consumer Group │ │ (订单服务) │ │ consumer-1/2/3 │ └─────────────┘ └───────────────────┘

Broker

Broker 是 Kafka 集群中的服务节点,负责接收 Producer 发来的消息、将消息持久化到磁盘,以及向 Consumer 提供读取服务。每个 Broker 都有唯一的 broker.id(整数)标识。生产环境通常部署 3 个或更多 Broker 以保证高可用。

Topic

Topic 是消息的逻辑分类,类似于数据库中的"表名"或文件系统中的"目录"。Producer 向特定 Topic 写入消息,Consumer 订阅 Topic 进行消费。Topic 名称在集群内唯一,命名通常采用 业务.子系统.事件类型 格式,如 ecommerce.order.created

Partition(分区)

每个 Topic 被分割为多个 Partition,这是 Kafka 实现高吞吐量和水平扩展的核心机制。每个 Partition 是一个有序、不可变的消息序列,消息以追加写入的方式添加到末尾,并被分配一个从 0 开始单调递增的整数编号——即 Offset

Replica(副本)与 Leader/Follower

每个 Partition 可以配置多个 Replica(副本因子,replication-factor),分布在不同的 Broker 上。副本中有且只有一个 Leader,负责处理所有读写请求;其余副本为 Follower,持续从 Leader 同步数据。当 Leader 所在 Broker 宕机时,从 ISR 中选出新的 Leader。

Kafka 的独特设计哲学

顺序写磁盘

Kafka 将消息追加写入磁盘文件(顺序 I/O),而非随机写入。现代磁盘的顺序写速度可达 600 MB/s,与内存的顺序读写性能相近,远优于随机写的 ~100 次/秒。这是 Kafka 高吞吐量的底层基础之一。

零拷贝(Zero-Copy)

传统数据发送需要 4 次数据拷贝:磁盘 → 内核缓冲区 → 用户空间 → Socket 缓冲区 → 网卡。Kafka 利用 Linux 的 sendfile() 系统调用,跳过用户空间,只需 2 次拷贝(磁盘 → 内核缓冲区 → 网卡),显著降低 CPU 开销和延迟。

零拷贝 vs 传统拷贝 传统方式(4次拷贝,2次系统调用): 磁盘 ──DMA──▶ 内核Buffer ──CPU──▶ 用户空间 ──CPU──▶ Socket Buffer ──DMA──▶ 网卡 零拷贝 sendfile()(2次拷贝,1次系统调用): 磁盘 ──DMA──▶ 内核Buffer ──DMA──▶ 网卡

PageCache 利用

Kafka 不在 JVM 堆中缓存消息,而是依赖操作系统的 PageCache(页缓存)。当 Consumer 消费最近写入的消息时,数据通常仍在 PageCache 中,无需从磁盘读取,实现了"写后即读"的高速访问。这也意味着 Kafka 进程重启后,PageCache 中的数据不会丢失(由 OS 管理)。

与 RabbitMQ / RocketMQ 对比

特性KafkaRabbitMQRocketMQ
吞吐量百万级 msg/s万级 msg/s十万级 msg/s
消息保留按时间/大小保留(默认7天)消费即删除消费即删除(可配置)
消息回溯支持(任意 Offset)不支持支持(时间点)
消费模式Pull(拉取)Push(推送)Push + Pull
消费顺序分区内有序队列内有序分区内有序
延迟毫秒级(低吞吐场景可达亚毫秒)微秒级毫秒级
协议自有协议(TCP)AMQP自有协议
生态最丰富(Flink/Spark/Debezium)较丰富阿里云生态

ZooKeeper vs KRaft

Kafka 长期依赖 Apache ZooKeeper 存储集群元数据(Broker 注册、Topic 分区信息、Consumer Offset 等)。Kafka 3.x 引入了 KRaft(Kafka Raft Metadata Mode),将元数据管理内置化,彻底移除 ZooKeeper 依赖。

特性ZooKeeper 模式KRaft 模式(3.x)
元数据存储ZooKeeper 集群Kafka 内置 Raft 日志
部署复杂度需单独维护 ZK 集群(3节点)单进程,无外部依赖
Controller 选举ZK 临时节点竞争Raft 算法
分区数上限~20 万(ZK 性能瓶颈)数百万(理论)
生产可用稳定(老版本)Kafka 3.3+ 生产可用

新项目推荐 KRaft 模式:Kafka 4.0 计划完全移除 ZooKeeper 支持。新建集群应直接使用 KRaft 模式(--bootstrap-controller)。现有 ZooKeeper 集群可通过迁移工具(kafka-storage.sh)无停机升级。

核心名词解释

关键理解:Kafka 中 Consumer Group 数量 = 并发消费者组数,Consumer 实例数(单个 Group 内)= 并行消费线程数,且受 Partition 数量上限约束。若 Consumer 数量超过 Partition 数量,多余的 Consumer 将处于空闲状态。