Apache Kafka 是当前使用最广的分布式消息队列与事件流平台。它由 LinkedIn 于 2011 年开源、捐赠给 Apache 基金会,核心解决两类问题:一是让多个系统之间以高吞吐、可回放的方式传递事件数据;二是把传统“投递即删”的消息队列升级为可持久化、可按时间重放的分布式提交日志。Kafka 以 Topic/Partition 组织数据,分区内顺序写盘、副本机制(ISR)保证高可用,配合消费者组实现负载均衡与水平扩展,单集群可支撑每秒数百万条消息、每天数万亿条事件。2025 年 3 月发布的 4.0 版本已彻底移除 ZooKeeper,全面转向 KRaft 元数据模式。本文按照“为什么需要—安装—上手—核心能力—生产部署”五步展开,并附同类选型对比、常见误区与面试题,帮助读者直接上手。

岗位关联

掌握 Kafka 是 AI 与大数据从业者的基础设施基本功:几乎所有实时数据管道、流式数仓与事件驱动架构都跑在 Kafka 之上。会部署、会调优、会监控 Kafka,是数据工程师、后端工程师与 SRE 的核心竞争力。

目录
  1. 为什么需要 Kafka:从“投递即删的队列”到“可回放的分布式日志”
  2. 安装与环境配置:4 步就绪(Kafka 4.0 / KRaft 单节点)
  3. 快速上手:5 分钟跑通“生产-消费”闭环
  4. 核心能力详解:4 大支柱
  5. 生产部署与监控:从上线到运维
  6. 版本迭代
  7. AI 应用场景
  8. 常见误区
  9. 面试题
  10. 参考来源
工具类型
分布式消息队列 / 事件流平台(开源)
开发商
Apache 软件基金会(2011 年由 LinkedIn 开源)
开源协议
Apache 2.0(可商用)
GitHub Stars
无
主要语言
Java / Scala
当前版本
4.0.x(2025-03 发布 4.0.0,KRaft-only)
安装方式
二进制解压即用 / 官方 Docker 镜像
上手难度
★★★☆☆(中等)
适合人群
后端工程师·数据工程师·SRE·系统架构师
同类工具
RabbitMQ·Apache Pulsar·RocketMQ
托管服务
无

速览卡是工具类内容的固定首屏模块:30 秒判断「这工具是什么、能不能商用、适不适合我」。

为什么需要 Kafka:从“投递即删的队列”到“可回放的分布式日志”

传统消息队列(如 RabbitMQ)与 RPC 直连在高吞吐场景下有三类典型瓶颈:一是吞吐上限,单机队列在每秒十万级以上写入时开始出现性能拐点;二是语义不足,消息被消费者确认(ACK)后即删除,无法重放历史数据,失败补偿只能靠业务层另建存储;三是扩展困难,队列集群的横向扩容往往伴随路由规则与运维复杂度的剧增。

Kafka 以“分布式提交日志”为核心理念解决这些问题:每个 Topic 按 Partition(分区)拆分,分区内消息顺序追加写入磁盘,写入路径采用顺序 IO、页缓存与零拷贝传输,单 Broker 即可支撑百万级消息/秒;消息不因消费而删除,由保留策略(时间/大小/压缩)统一管理,消费者通过 offset(偏移量,即消息在分区内的游标位置)自行推进,随时可回放。副本机制与 ISR(同步副本,即与领导者保持一致的副本集合)负责故障切换。

与普通消息队列的气质差异在于:RabbitMQ 强调“投递与路由”,Kafka 强调“记录与重放”。前者适合任务分发,后者适合事件流基础设施建设。这也是 Kafka 成为实时数仓、日志管道、CDC(变更数据捕获)事实标准的原因。

安装与环境配置:4 步就绪(Kafka 4.0 / KRaft 单节点)

步骤一 · 安装前置:Kafka 4.0 要求 JDK 17 及以上,先确认 java -version 输出为 17+。

步骤二 · 下载与解压:从 Apache 官方下载二进制包(文件名格式 kafka_2.13-4.0.0.tgz),解压后所有命令均位于 bin/ 目录。若官方源较慢,可改用 kafka.apache.org/downloads 页面列出的镜像地址。

步骤三 · 初始化 KRaft 存储:4.0 起不再有 ZooKeeper,首次启动前必须生成集群 ID 并格式化元数据存储目录,否则 broker 无法启动。

步骤四 · 启动与验证:启动 broker 后创建主题并完成一次生产/消费,确认端到端可用。

bash17 行
# 1. 前置检查:JDK 17+java -version # 2. 下载并解压(4.0.0 为当前最新正式版)wget https://downloads.apache.org/kafka/4.0.0/kafka_2.13-4.0.0.tgztar -xzf kafka_2.13-4.0.0.tgz && cd kafka_2.13-4.0.0 # 3. 生成集群 ID 并格式化 KRaft 存储目录(4.0 起无需 ZooKeeper)KAFKA_CLUSTER_ID="$(bin/kafka-storage.sh random-uuid)"bin/kafka-storage.sh format -t "$KAFKA_CLUSTER_ID" -c config/kraft/server.properties # 4. 启动单节点 broker(controller 与 broker 角色合一)bin/kafka-server-start.sh config/kraft/server.properties # 5. 另开终端:创建主题并验证bin/kafka-topics.sh --bootstrap-server localhost:9092 --create --topic quickstart-events --partitions 3 --replication-factor 1bin/kafka-topics.sh --bootstrap-server localhost:9092 --list

快速上手:5 分钟跑通“生产-消费”闭环

最小可用流程的思路是:先建主题,再用命令行生产者写入、命令行消费者读出,最后用代码客户端验证 API 集成。单节点集群副本因子只能设为 1,生产环境再按集群规模调整。

1. 创建主题:执行 bin/kafka-topics.sh --bootstrap-server localhost:9092 --create --topic quickstart-events --partitions 3 --replication-factor 1,分区数设为 3 以观察并行消费。

2. 启动生产者:执行 bin/kafka-console-producer.sh --bootstrap-server localhost:9092 --topic quickstart-events,输入若干行文本并回车,Ctrl+C 退出。

3. 启动消费者:另开终端执行 bin/kafka-console-consumer.sh --bootstrap-server localhost:9092 --topic quickstart-events --from-beginning,可看到之前写入的全部消息——这验证了 Kafka“消费不删消息、可回放”的日志特性。

4. 代码集成:Kafka 提供 Java、Python、Go 等多语言客户端。Python 最常用的是 kafka-python 与 confluent-kafka(后者封装 librdkafka、性能更优),先用 pip install kafka-python 安装。

运行两个文件即可看到消息被组内消费者按分区分摊读取。进阶技巧:用 bin/kafka-consumer-groups.sh --bootstrap-server localhost:9092 --describe --group order-service 查看每个分区的消费滞后量(LAG),这是日常运维最常用的检查命令。

python25 行
# producer.py:生产者(kafka-python)from kafka import KafkaProducer producer = KafkaProducer(    bootstrap_servers="localhost:9092",    acks="all",                        # 等待所有 ISR 副本确认,防丢消息    key_serializer=lambda k: k.encode("utf-8"),    value_serializer=lambda v: v.encode("utf-8"),)producer.send("quickstart-events", key="order-1001", value="created")producer.flush()                       # 阻塞直到发送完成print("sent") # consumer.py:消费者(消费者组)from kafka import KafkaConsumer consumer = KafkaConsumer(    "quickstart-events",    bootstrap_servers="localhost:9092",    group_id="order-service",          # 同一组内分区被成员分摊消费    auto_offset_reset="earliest",      # 无已提交 offset 时从最早开始    enable_auto_commit=True,           # 自动提交 offset,生产环境建议手动提交)for msg in consumer:    print(f"partition={msg.partition} offset={msg.offset} key={msg.key} value={msg.value}")

核心能力详解:4 大支柱

支柱一 · 分布式提交日志与分区并行。Kafka 将每个主题的消息追加写入分区的日志段(Segment)文件,整体路径是“顺序写磁盘 + 页缓存 + 零拷贝(sendfile)发送”,顺序 IO 与零拷贝让单分区吞吐可达每秒数十 MB。分区是并行的基本单位:生产者按 key 哈希或轮询把消息写入不同分区,不同分区的数据可被不同 Broker 与消费者并行处理,集群吞吐通过增加分区与节点线性扩展。

支柱二 · 副本机制与高可用。每个分区有多个副本(replica),其中一个为领导者(Leader)、其余为跟随者(Follower),只有领导者处理读写。ISR(In-Sync Replicas,同步副本)是持续跟上领导者数据的副本集合;领导者故障时从 ISR 中选举新领导者。配合生产者 acks=all 与 min.insync.replicas 参数,可以做到在 N 个副本节点中有 N-1 个故障时不丢已确认消息。

支柱三 · Exactly-once 语义。Kafka 0.11 引入幂等生产者与事务(KIP-98),生产者侧通过 PID + 序列号实现幂等写入,事务保证一批消息跨分区的原子写入。配合“读取-处理-写回”模式(如 Kafka Streams),可以构建端到端精确一次处理,这是流计算与传统消息队列拉开差距的关键能力。

支柱四 · KRaft 元数据自管理。自 2.8 版本引入、4.0 起全面接管:集群的主题、分区、Broker 状态等元数据由一组专属的 Controller 节点通过 Raft 协议仲裁与存储,替代了原 ZooKeeper 模式。相比 ZooKeeper,KRaft 减少了运维组件、元数据变更延迟更低、故障切换更快,并支持单节点快速起步。

生产部署与监控:从上线到运维

部署方式一 · 多节点 KRaft 集群(生产推荐)。将 controller 与 broker 角色分离:3 个 Controller 节点组成元数据仲裁组(奇数,防脑裂),N 个 Broker 节点承载数据。每个节点在 config/kraft/server.properties 中通过 process.roles=controller 或 process.roles=broker 指定角色;Broker 需设置 advertised.listeners 为客户端可访问地址、log.dirs 指向独立数据盘。启动方式仍为 kafka-server-start.sh config/kraft/server.properties,但每个节点使用各自的配置文件。建议同步配置:replication.factor=3、min.insync.replicas=2、log.retention.hours=168(默认 7 天),并按峰值吞吐 × 保留时间规划分区数。

部署方式二 · 容器化与 Kubernetes。Apache 官方已发布 Docker 镜像 apache/kafka,单节点快速验证可执行 docker run -p 9092:9092 apache/kafka:4.0.0。生产环境推荐用 Strimzi Operator 在 Kubernetes 上以声明式方式管理 Kafka 集群、Topic 与用户权限,Strimzi 负责滚动升级与故障自愈,适合已有 K8s 基础设施的团队。

可观测性。Kafka 通过 JMX(Java 管理扩展,Java 应用暴露运行指标的标准接口)暴露指标,生产环境通常用 Prometheus JMX exporter 或 kafka-exporter 采集,Grafana 展示。必须盯住的四类指标:① 副本健康——UnderReplicatedPartitions(分区副本数少于配置的个数)持续大于 0 说明有副本落后;② 入站负载——BytesInPerSec、RequestsPerSec;③ 控制器状态——ActiveControllerCount 应为 1;④ 消费滞后——kafka-consumer-groups.sh --describe 的 LAG 列,滞后持续增长说明消费者处理能力不足,可用 Linkedin 开源的 Burrow 做滞后告警。分区不均衡时可用 Cruise Control 自动执行分区重平衡。

<p class="para-label">避坑清单:</p>

<ul class="dash-list"><li>分区数只能增不能减,且每个分区都带来文件句柄、日志段滚动与重平衡开销——上线前按目标吞吐 × 保留天数估算并留 20%-30% 冗余,不要随意设上千分区。</li><li>可靠性是配置组合的结果:只设 replication.factor=3 不够,必须同时满足生产者 acks=all 与 broker 端 min.insync.replicas=2,否则副本落后时写入看似成功、故障切换仍会丢数据。</li><li>4.0 起 ZooKeeper 模式与 --zookeeper 参数、旧 config/server.properties 已彻底移除,照抄 2.x/3.x 教程会直接启动失败;先确认版本、改用 config/kraft/server.properties 并补齐 Java 17。</li></ul>

维度KafkaRabbitMQApache PulsarRocketMQ
定位分布式事件流平台通用消息代理(任务队列)多租户事件流平台电商级消息队列
编排范式发布-订阅 + 消费者组,日志追加模型AMQP 交换机-绑定-队列灵活路由发布-订阅 + 分层存储(BookKeeper)发布-订阅 + 队列,支持事务与延迟消息
类型约束分区内严格有序,跨分区不保证队列级 FIFO,支持 TTL 与死信队列按 key 有序,支持多租户隔离顺序消息、事务消息、定时/延迟等级
学习曲线中(分区/ISR/offset 概念较多)低(上手快,概念少)中高(组件多,运维复杂)中(中文资料丰富)
生态集成极广(Connect/Streams/流计算/湖仓)广泛(Spring AMQP、Celery 等)中(云厂商支持增长中)集中于阿里云生态
生产部署KRaft 自管元数据,3 控制器 + N Broker单机部署简单,集群轻量依赖 BookKeeper,组件多NameServer + Broker 双组件
LicenseApache 2.0MPL 2.0Apache 2.0Apache 2.0
适合谁大数据流平台/实时数仓团队中小业务任务队列与复杂路由多租户隔离与跨地域复制需求企业阿里系用户与事务消息场景

选型建议:日志采集、事件流、实时数仓等“高吞吐 + 可回放”场景首选 Kafka;业务解耦、路由灵活、希望快速上手的任务队列选 RabbitMQ;需要多租户隔离、跨地域复制或存储与计算独立扩缩容时评估 Pulsar;深度使用阿里云、依赖事务与定时消息则选 RocketMQ。

版本迭代

Kafka 自 2011 年由 LinkedIn 开源以来,主线是“从可用走向元数据自管理”:2011 年进入 Apache 孵化、2012 年成为顶级项目;0.8 引入副本机制奠定高可用,1.0 走向成熟;2021 年 2.8 引入 KRaft(KIP-500)逐步替代 ZooKeeper,历经 3.x 数个版本过渡,至 4.0(2025-03)彻底移除 ZooKeeper、最低要求 Java 17,进入 KRaft-only 时代。

版本时间变化提升
Kafka 2.82021-04引入 KRaft(KIP-500)去除 ZooKeeper 依赖的元数据模式首次可用,为后续去依赖铺路
Kafka 3.32022-10KRaft 达到生产就绪元数据仲裁与分区搬迁趋于稳定,官方建议新集群优先采用 KRaft
Kafka 3.72024-02ZooKeeper 弃用第一阶段新集群默认 KRaft,老旧配置进入弃用流程,为 4.0 清理做准备
Kafka 3.92024-10元数据版本迁移(KIP-1013)支持 KRaft 元数据跨版本无缝升级,状态机性能与稳定性优化
Kafka 4.02025-03彻底移除 ZooKeeper仅 KRaft 模式,最低运行环境提升至 Java 17,移除 Scala 2.12 构建与过期配置
结论

版本主线清晰——元数据自管化(去 ZooKeeper)与运行环境现代化(Java 17)。官方未发布跨大版本的统一基准测试,社区与官方发布说明的实测反馈显示,KRaft 模式下控制器故障切换时间从 ZooKeeper 时代的数十秒级降至秒级。选型时不必追求最新小版本,但新项目应直接规划 4.0 及以上,避免走 2.x/3.x 的 ZooKeeper 迁移弯路。

AI 应用场景

场景 1:日志与埋点事件流采集

阶段:数据管道·事件流接入

解决的问题:业务日志、埋点、审计事件量巨大且突发,直接写库会拖垮在线系统;Kafka 以分区并行与顺序写盘吸收每秒百万级写入,消息按保留策略持久化,供多个下游异步消费,实现写入与处理的完全解耦。

具体案例:领英(LinkedIn)官方披露其 Kafka 集群每天处理超过 7 万亿条消息事件(2019 年公开数据),支撑全公司日志与指标采集。典型做法是采集端只写 Kafka 缓冲,下游入库按自身速率消费,峰值写入被削峰填谷地摊平,数据库避免被打爆。

场景 2:微服务异步解耦与削峰填谷

阶段:数据管道·异步消息

解决的问题:大促、秒杀场景下,下单、支付、库存、通知串行调用时峰值 QPS 超过下游承受能力;Kafka 作为事件总线,订单服务只写事件,支付/库存/积分等消费者各自按容量限速消费、互不阻塞。

具体案例:某电商订单系统改造后,订单事件写入由直连数据库(约 1 万 QPS 瓶颈)改为写入 Kafka(按集群规模与分区数可承载 10 万级事件/秒),下游按各自处理能力消费,订单接口峰值吞吐提升一个数量级、峰值期不再雪崩。

场景 3:实时数仓与流式计算

阶段:数据管道·流处理

解决的问题:离线数仓 T+1 延迟高,无法支撑实时风控、实时报表;Kafka 作为流式数据中枢,CDC 工具(如 Debezium)把数据库变更实时写入 Kafka,Kafka Streams/ksqlDB 或 Flink 消费后实时聚合入仓,原始事件保留在 Kafka 中可追溯回放。

具体案例:某金融风控团队用 Debezium 将交易库变更实时同步到 Kafka,以 Flink 消费聚合,风控事件处理延迟从分钟级降到秒级;同时利用 Kafka 的消息保留机制回放历史变更事件,支撑对账与故障排查。

常见误区

误区我理解的 Kafka 和 RabbitMQ 一样,消费者确认(ACK)后消息就从队列里删掉了,所以不能重复消费同一批消息。

正解Kafka 是分布式提交日志而非队列:消息按保留策略(默认 log.retention.hours=168,7 天)统一管理,消费只推进消费者自己的 offset 游标、不删除消息。任何消费者组都可以通过 --from-beginning 或重置 offset 重新消费历史事件,这是事件溯源、数据重放与故障恢复的基础能力。

为何常见:大多数入门者先用 RabbitMQ/Redis 队列建立“ACK 即删”的心智模型,接触 Kafka 时未意识到日志模型与队列模型的本质区别。

误区把分区数从 10 加到 1000,集群吞吐应该线性增长,加分区就是免费的性能优化。

正解分区提升的是并行度上限,不是无脑吞吐。分区过多会带来文件句柄、日志段滚动、副本同步与消费者重平衡(Rebalance)的额外开销,且分区只能增加不能减少。官方文档与社区实践长期建议单 Broker 分区数控制在数千个以内,合理做法是按“峰值吞吐 × 保留天数”估算分区数,再留 20%-30% 冗余。

为何常见:看到“分区是并行最小单位”就推导出“分区越多越快”,忽略了每个分区的写放大与管理成本,也忽略了 Kafka 官方明确提示的容量限制。

误区组里 6 个分区消费不过来,我把消费者水平扩容到 12 个,消费速度应该翻倍。

正解一个分区同一时刻只被组内的一个消费者消费,分区是分配的最小单位。消费者数大于分区数时,多出来的消费者完全空闲。加速消费只能靠增加分区数(前提是分区已足够多),而不是无限加消费者。在 kafka-consumer-groups.sh --describe 中可以看到组内成员数大于分区数时必然出现空转成员。

为何常见:误把“组内并行”理解为“分区内并行”,忽略了 Kafka 的分配粒度是分区而非单条消息。

误区Kafka 官方说高可靠,所以只要用了 Kafka,消息就一定不会丢。

正解可靠性是一组配置组合的结果:生产者 acks=all、broker 端 replication.factor≥3 且 min.insync.replicas≥2、消费者配合合理的提交策略,缺一个都可能在不同故障场景下丢消息或重复消费。例如 acks=1 时 leader 落盘即返回,leader 崩溃且副本未同步就丢;ISR 收缩到低于 min.insync.replicas 时 acks=all 写入会被拒绝,这是防丢设计而非故障。

为何常见:官方宣传与社区口碑侧重“高吞吐高可靠”,读者未细读配置文档,把能力上限当成了默认行为。

误区网上教程都是先 `bin/zookeeper-server-start.sh config/zookeeper.properties` 启动 ZooKeeper,再启动 broker,我照抄就行。

正解Kafka 4.0 已彻底移除 ZooKeeper,仅支持 KRaft 模式:先执行 kafka-storage.sh format 生成并格式化元数据目录,再直接启动 broker/controller,所有命令行统一使用 --bootstrap-server 而非 --zookeeper,旧 config/server.properties 已被 config/kraft/server.properties 取代,且最低要求 Java 17。

为何常见:大量教程与博客停留在 2.x/3.x 的 ZooKeeper 模式,4.0 发布后内容更新滞后,搜索引擎优先返回旧教程,照着做必然启动失败。

面试题

Q1. Kafka 中消息在 Topic 内进行水平划分的最小存储单元是?

单选题 · easy

  • A.Broker(代理节点)
  • B.Partition(分区)← 正确答案
  • C.Cluster(集群)
  • D.Segment(日志段)

答案:B。Partition 是 Kafka 并行处理与有序保证的基本单元,Topic 的数据按分区分散到不同 Broker。Broker 是运行 Kafka 的进程,Cluster 是节点集合,Segment 只是分区日志文件的切片,三者都不是水平划分单元。

Q2. Kafka 最初由哪家公司开发并开源?

单选题 · easy

  • A.阿里巴巴(内部中间件团队)
  • B.LinkedIn(领英)← 正确答案
  • C.谷歌(Google 云平台团队)
  • D.亚马逊(AWS 托管团队)

答案:B。Kafka 由 LinkedIn 的 Jay Kreps 等人于 2010 年前后开发,2011 年开源并进入 Apache 孵化,2012 年成为 Apache 顶级项目。阿里开源的是 RocketMQ。

Q3. 消息消费后不会立即删除,Kafka 默认保留时长由哪个配置项控制?

单选题 · easy

  • A.log.retention.hours(日志保留小时数)← 正确答案
  • B.max.poll.records(单次拉取条数)
  • C.auto.offset.reset(初始偏移量策略)
  • D.fetch.max.bytes(单次拉取字节上限)

答案:A。Kafka 采用日志保留模型,log.retention.hours 默认 168(7 天),到期按段删除。B、D 都是消费者的拉取参数,C 决定消费者没有已提交 offset 时的起点,均与保留时长无关。

Q4. 同一个消费者组内分区数为 6、消费者数为 8 时,实际参与消费的消费者有几个?

单选题 · mid

  • A.2 个
  • B.6 个← 正确答案
  • C.8 个
  • D.14 个

答案:B。一个分区同一时刻只能被组内一个消费者消费,分区是分配的最小单位。分区数 6 个、消费者 8 个时,6 个消费者各分到 1 个分区,另外 2 个消费者空闲。要提高消费速度,应增加分区数而非消费者数。

Q5. 生产者参数 acks 设置为哪个值时,必须等待所有同步副本(ISR)确认才算发送成功?

单选题 · mid

  • A.0(不等待任何确认)
  • B.1(仅等领导者节点确认)
  • C.all(等所有 ISR 副本确认)← 正确答案
  • D.2(等待任意两个副本确认)

答案:C。acks=all(与 -1 等价)表示分区所有 ISR 副本写入成功后才返回,配合 min.insync.replicas 才能做到不丢已确认消息。acks=0 不等待、acks=1 仅等 leader,都存在故障时丢数据的窗口;不存在 acks=2 的取值。

Q6. 关于 Kafka 的消息有序性,下列说法正确的是?

多选题 · mid

  • A.同一分区内,消息按写入顺序存储并消费← 正确答案
  • B.同一主题内,跨分区的消息全局有序
  • C.分区数为 1 的主题可以做到主题级有序← 正确答案
  • D.有序性不受分区数影响,Kafka 天然全局有序

答案:AC。Kafka 的有序保证粒度是“分区内有序”:同一分区按写入顺序追加、按 offset 顺序消费;跨分区不保证顺序。当主题只有 1 个分区时,全局有序自然成立。B、D 错误地把有序性外推到多分区场景。

Q7. KRaft 模式下,集群的元数据(主题、分区、Broker 状态)由什么组件负责存储与仲裁?

单选题 · mid

  • A.独立部署的 ZooKeeper 集群
  • B.Controller 仲裁组(Kafka 自身角色)← 正确答案
  • C.任意一个数据节点 Broker
  • D.外部关系型数据库(如 MySQL)

答案:B。KRaft 模式下,元数据由配置了 controller 角色的 Kafka 节点通过 Raft 协议仲裁和持久化,4.0 起这是唯一模式。ZooKeeper 已彻底移除;普通 broker 没有元数据仲裁职责;Kafka 不依赖外部数据库。

Q8. 以下哪些是 Kafka 4.0 相比 3.x 的破坏性变更?

多选题 · hard

  • A.彻底移除 ZooKeeper,仅支持 KRaft 模式← 正确答案
  • B.最低运行环境从 Java 8 提升到 Java 17← 正确答案
  • C.取消 --zookeeper 命令行参数,统一使用 --bootstrap-server← 正确答案
  • D.分区数必须为偶数,奇数分区会被拒绝创建

答案:ABC。4.0 移除 ZooKeeper、要求 Java 17、删除全部 ZooKeeper 相关 CLI 参数与旧配置项,这些都会导致旧命令直接报错。D 是杜撰的限制,Kafka 对分区数奇偶没有要求。

Q9. 生产环境保证 Kafka“不丢消息”,通常需要哪些配置组合?

多选题 · hard

  • A.副本因子 replication.factor 设置为 3← 正确答案
  • B.生产者 acks=all 且 min.insync.replicas=2← 正确答案
  • C.消费者 enable.auto.commit=false 并手动提交 offset← 正确答案
  • D.每个消费者使用全局唯一的随机 group.id

答案:ABC。A 保证分区有冗余副本;B 保证写入必须在足够多副本落盘后才确认;C 保证消费者处理完成前不提交位移,避免崩溃时丢已拉取未处理的消息。D 反而会造成重复消费,与防丢无关。

Q10. 当 min.insync.replicas=2、副本因子为 3,某分区 ISR 收缩到只剩 1 个副本时,生产者以 acks=all 写入该分区会怎样?

单选题 · extreme

  • A.正常写入,等副本追平后再同步
  • B.写入成功,但是可能静默丢失数据
  • C.写入被拒绝并抛出 NotEnoughReplicas 异常← 正确答案
  • D.自动降低 acks 级别以继续写入

答案:C。当分区 ISR 数量低于 min.insync.replicas 时,acks=all 的写入会直接失败(NotEnoughReplicasException),这是 Kafka 防止“假成功”的设计:宁可拒绝写入也不让消息在副本不足时被确认。此时正确做法是告警并排查副本恢复,而非降级 acks。

参考来源