00 · 起点 / Entry

Apache Kafka:系统理解 + 面试教程

把 Kafka 当成一条分布式可重放的提交日志来理解——而不是"更快的消息队列"。这是中高级面试里区分背题和真懂的分水岭。

基于版本:Apache Kafka 4.3(2026-05),KRaft 唯一元数据模式 · 阅读时间:约 2–3 小时 · 代码验证状态:代码示例基于 kafka-clients 4.x,未在本机逐一运行。

01适合谁

面向已经用过 Kafka、但没深究内部机制的 Java 后端工程师。具体说,三条前置能力:

  • 用过 Kafka 的 topic / producer / consumer,能在本机跑通一个 hello-world:建 topic、发几条消息、用消费组读出来。
  • 懂 Java,能读 KafkaProducer / KafkaConsumer 的代码——看得懂 send() 返回 Future、poll() 拉一批、commitSync() 提交位移这些调用。
  • 理解基本并发与网络 I/O:知道什么是阻塞调用、什么是磁盘顺序写 vs 随机写、一次网络往返(RTT)意味着延迟。

02不适合谁

三类读者在别处能拿到更对口的资源:

  • 零基础、没碰过消息队列的人:这里不从"什么是消息队列"讲起。先看 Kafka 官方 Quickstart 跑通第一个 producer/consumer,再回来。
  • 只想要 API 速查的人:要查某个配置项或方法签名,直接读 官方 Configuration 文档 比这套教程快——这里讲的是"为什么",不是参数字典。
  • 要专精 Kafka Streams 的人:本教程只把 Streams 当"学完之后"的延伸方向。流处理 DSL、状态存储、窗口聚合请看 本仓库的 Kafka Streams 子教程,或 Kafka Streams 官方文档。

03读完之后你能做到什么

你能把 Kafka 的每一个可靠性配置追溯到"它在复制一条日志"这条主线上——面试被问"怎么保证不丢消息"时,不是背出 acks=all,而是能从 ISR 和高水位推导出:为什么单独 acks=all 不够、必须和 min.insync.replicas / replication.factor / 关闭 unclean 选举一起上。

落到可验证的能力,读完这套教程之后:

  • 配置出一个端到端不丢消息的 producer-consumer 组合,并能说清每一项配置挡住的是哪种故障。
  • 判断一个给定场景该用 Kafka 还是 RabbitMQ,并讲出判据(吞吐 / 可重放 / 路由复杂度 / 运维成本)。
  • 解释 exactly-once 的真实边界——它只在 Kafka 的"消费-转换-生产"闭环内成立,不覆盖数据库写、REST 调用这些外部副作用。
  • 推导一个写请求从 producer 到对 consumer 可见,中间经过 ISR、高水位、提交位移哪些环节,以及每个环节的失败模式。
  • 定出一个 topic 的分区数,并权衡消费并行度、顺序范围、再平衡成本、故障切换开销之间的取舍。

一句话本质

Kafka 不是消息队列,而是一个分布式、可重放、按分区切分的提交日志(commit log)。

一旦把它当"日志"而非"队列"理解,这些就都顺理成章:消息被消费后不删除(可重放)、消费位移(offset)由消费者维护而非 broker、顺序只在单个分区内保证、高吞吐来自顺序日志 I/O + page cache + 零拷贝、副本机制就是在复制这条日志、连 4.2 新出的 share group 队列语义也是架在日志之上的一层。中高级面试里能不能把 Kafka 框成"分布式可重放的分区日志"而不是"更快的 MQ",就是区分背题和真懂的分水岭。

04现状速览(截至 2026-06)

什么定论、什么在动、什么已被取代

稳定(多年未变):日志存储模型、核心 producer / consumer API;Tiered Storage(KIP-405)3.9(2024-11)已 GA。

近 12 个月的变化:4.0(2025-03)彻底删除 ZooKeeper,KRaft 成为唯一元数据模式;新消费者再平衡协议 KIP-848(4.0 GA)改为 broker 端驱动的增量再平衡;"Queues for Kafka"(KIP-932 share group)4.2(2026-02)GA——原生队列语义、按记录 ack、不再受"消费者数 ≤ 分区数"限制。最新版 4.3(2026-05),约 3 版/年节奏。

已淘汰:ZooKeeper 模式(4.0 删除,不是可选项);经典 eager 再平衡协议(5.0 将移除);Java 8(4.0 移除,broker 需 Java 17、client 需 Java 11)。

是方向、但还没落地:Diskless Topics 直写 S3(KIP-1150)2026-03 仅设计通过,开源版尚无实现;AutoMQ / WarpStream 已商用。趋势是真的,但 vanilla Kafka 今天还不能直写 S3。

升级陷阱

不能从 ZooKeeper 集群直接跳到 4.0,必须先在 3.x 上迁移到 KRaft(3.9 是推荐的桥接版)。

05读之前:三个假象

流畅感不等于学会

Kafka 的文档和博客都好读,正因为好读,三种"感觉良好"会骗过你——它们都是假象:

· "我读得很顺"——顺,多半是因为这些词你早就熟悉(topic、offset、acks),熟悉不是学会。能复述名词,不等于能推导出 ISR 缩到 1 时 acks=all 为什么会静默退化。

· "我做题很快"——快,多半是碰上了套路题("Kafka 为什么快?顺序 I/O + 零拷贝")。换成"加了消费者反而 lag 更大,为什么"这种,速度立刻说明不了理解。

· "我没卡壳"——没卡壳,多半是还没碰到真正的 schema:把 Kafka 当队列时一路通畅,直到遇到"消费完为什么不删数据""offset 凭什么在消费者这侧"才会卡——那一卡,才是开始学的地方。

06概念地图

这张图是后面六章挂载细节的骨架。中心是一条分区日志,其余所有角色——producer、consumer、broker、副本——都是围绕这条日志在做事。

Partition = 提交日志 append-only · 按 Offset 有序 消费不删数据 = 可重放 Topic / 主题 逻辑分类 切分为 Producer 按 key 哈希写入 写 Cluster KRaft controller quorum 元数据本身也是一条日志 Broker 持有 leader/follower 包含 持有 Consumer Group 读取,各自维护 offset offset 在消费者这侧 读 Replica / ISR 同步副本集 由 HW 控制可见性 同步
图 0.1Kafka 的概念全貌:六个角色环绕同一条分区日志。 注意:三件事——① 中心是"日志"不是"队列";② producer 写、consumer 读、replica 同步,都是围绕同一条分区日志在做事;③ offset 在 consumer 这侧,不在 broker。

07学习路径建议

顶部的 breadcrumb 是完整的线性顺序。不必每章都读——按目标挑路径:

  • 只想吃透原理、应付面试 → 01 概念 → 02 原理 → 06 自测。把心智模型和设计取舍立起来,再用题库逼自己开口推导。
  • 要动手搭系统 → 01 → 02 → 03 实操 → 04 陷阱 → 05 综合。从概念到代码到生产失败模式,最后用电商订单系统串起来。
  • 带读别人的 Kafka 代码 → 01 → 02 → 04 陷阱。先有词汇表和原理,再带着"这段代码会在哪种故障下出问题"的眼光去读 review。

08目录

09学完之后

这套教程把"分区日志"这个 schema 立稳。下一步的五个主题,各自在这个 schema 上加一层:

  • Kafka Streams——在日志之上加一套有状态流处理:把 topic 当输入流、本地状态存储当物化视图(KTable 就是 compaction 日志的内存投影)。→ 本仓库 Kafka Streams 子教程
  • Kafka Connect——在日志的两端加标准化的进出管道:source / sink 连接器,让"日志 ↔ 外部系统"不用每次手写 producer/consumer。→ 本仓库 Kafka Connect 子教程
  • Schema Registry——在写入日志的字节之上加一层契约:用版本化 schema 管住序列化格式,挡住 04 章那种"不兼容变更卡死消费者"。
  • share group 队列语义深入——在同一条日志上加按记录 ack 的队列视图(KIP-932),看它如何在不破坏日志模型的前提下摘掉"消费者数 ≤ 分区数"这条限制。
  • Pulsar 对比——换一种把"日志"和"计算 / 存储"解耦的架构:用 BookKeeper 分层存储对照 Kafka 的 broker 本地日志,看清两种设计在弹性与运维上的取舍。