Apache Kafka 是当前使用最广的分布式消息队列与事件流平台。它由 LinkedIn 于 2011 年开源、捐赠给 Apache 基金会,核心解决两类问题:一是让多个系统之间以高吞吐、可回放的方式传递事件数据;二是把传统“投递即删”的消息队列升级为可持久化、可按时间重放的分布式提交日志。Kafka 以 Topic/Partition 组织数据,分区内顺序写盘、副本机制(ISR)保证高可用,配合消费者组实现负载均衡与水平扩展,单集群可支撑每秒数百万条消息、每天数万亿条事件。2025 年 3 月发布的 4.0 版本已彻底移除 ZooKeeper,全面转向 KRaft 元数据模式。本文按照“为什么需要—安装—上手—核心能力—生产部署”五步展开,并附同类选型对比、常见误区与面试题,帮助读者直接上手。
掌握 Kafka 是 AI 与大数据从业者的基础设施基本功:几乎所有实时数据管道、流式数仓与事件驱动架构都跑在 Kafka 之上。会部署、会调优、会监控 Kafka,是数据工程师、后端工程师与 SRE 的核心竞争力。
目录
速览卡是工具类内容的固定首屏模块: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 后创建主题并完成一次生产/消费,确认端到端可用。
# 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),这是日常运维最常用的检查命令。
# 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>
| 维度 | Kafka | RabbitMQ | Apache Pulsar | RocketMQ |
|---|---|---|---|---|
| 定位 | 分布式事件流平台 | 通用消息代理(任务队列) | 多租户事件流平台 | 电商级消息队列 |
| 编排范式 | 发布-订阅 + 消费者组,日志追加模型 | AMQP 交换机-绑定-队列灵活路由 | 发布-订阅 + 分层存储(BookKeeper) | 发布-订阅 + 队列,支持事务与延迟消息 |
| 类型约束 | 分区内严格有序,跨分区不保证 | 队列级 FIFO,支持 TTL 与死信队列 | 按 key 有序,支持多租户隔离 | 顺序消息、事务消息、定时/延迟等级 |
| 学习曲线 | 中(分区/ISR/offset 概念较多) | 低(上手快,概念少) | 中高(组件多,运维复杂) | 中(中文资料丰富) |
| 生态集成 | 极广(Connect/Streams/流计算/湖仓) | 广泛(Spring AMQP、Celery 等) | 中(云厂商支持增长中) | 集中于阿里云生态 |
| 生产部署 | KRaft 自管元数据,3 控制器 + N Broker | 单机部署简单,集群轻量 | 依赖 BookKeeper,组件多 | NameServer + Broker 双组件 |
| License | Apache 2.0 | MPL 2.0 | Apache 2.0 | Apache 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.8 | 2021-04 | 引入 KRaft(KIP-500) | 去除 ZooKeeper 依赖的元数据模式首次可用,为后续去依赖铺路 |
| Kafka 3.3 | 2022-10 | KRaft 达到生产就绪 | 元数据仲裁与分区搬迁趋于稳定,官方建议新集群优先采用 KRaft |
| Kafka 3.7 | 2024-02 | ZooKeeper 弃用第一阶段 | 新集群默认 KRaft,老旧配置进入弃用流程,为 4.0 清理做准备 |
| Kafka 3.9 | 2024-10 | 元数据版本迁移(KIP-1013) | 支持 KRaft 元数据跨版本无缝升级,状态机性能与稳定性优化 |
| Kafka 4.0 | 2025-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 内进行水平划分的最小存储单元是?
- A.Broker(代理节点)
- B.Partition(分区)← 正确答案
- C.Cluster(集群)
- D.Segment(日志段)
答案:B。Partition 是 Kafka 并行处理与有序保证的基本单元,Topic 的数据按分区分散到不同 Broker。Broker 是运行 Kafka 的进程,Cluster 是节点集合,Segment 只是分区日志文件的切片,三者都不是水平划分单元。
Q2. Kafka 最初由哪家公司开发并开源?
- A.阿里巴巴(内部中间件团队)
- B.LinkedIn(领英)← 正确答案
- C.谷歌(Google 云平台团队)
- D.亚马逊(AWS 托管团队)
答案:B。Kafka 由 LinkedIn 的 Jay Kreps 等人于 2010 年前后开发,2011 年开源并进入 Apache 孵化,2012 年成为 Apache 顶级项目。阿里开源的是 RocketMQ。
Q3. 消息消费后不会立即删除,Kafka 默认保留时长由哪个配置项控制?
- 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 时,实际参与消费的消费者有几个?
- A.2 个
- B.6 个← 正确答案
- C.8 个
- D.14 个
答案:B。一个分区同一时刻只能被组内一个消费者消费,分区是分配的最小单位。分区数 6 个、消费者 8 个时,6 个消费者各分到 1 个分区,另外 2 个消费者空闲。要提高消费速度,应增加分区数而非消费者数。
Q5. 生产者参数 acks 设置为哪个值时,必须等待所有同步副本(ISR)确认才算发送成功?
- 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 的消息有序性,下列说法正确的是?
- A.同一分区内,消息按写入顺序存储并消费← 正确答案
- B.同一主题内,跨分区的消息全局有序
- C.分区数为 1 的主题可以做到主题级有序← 正确答案
- D.有序性不受分区数影响,Kafka 天然全局有序
答案:AC。Kafka 的有序保证粒度是“分区内有序”:同一分区按写入顺序追加、按 offset 顺序消费;跨分区不保证顺序。当主题只有 1 个分区时,全局有序自然成立。B、D 错误地把有序性外推到多分区场景。
Q7. KRaft 模式下,集群的元数据(主题、分区、Broker 状态)由什么组件负责存储与仲裁?
- 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 的破坏性变更?
- 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“不丢消息”,通常需要哪些配置组合?
- 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 写入该分区会怎样?
- A.正常写入,等副本追平后再同步
- B.写入成功,但是可能静默丢失数据
- C.写入被拒绝并抛出 NotEnoughReplicas 异常← 正确答案
- D.自动降低 acks 级别以继续写入
答案:C。当分区 ISR 数量低于 min.insync.replicas 时,acks=all 的写入会直接失败(NotEnoughReplicasException),这是 Kafka 防止“假成功”的设计:宁可拒绝写入也不让消息在副本不足时被确认。此时正确做法是告警并排查副本恢复,而非降级 acks。
参考来源
- webpageApache Kafka 官网项目首页、下载入口与发布说明