← 每日面试题 学习看板

Kafka如何保证消息不丢失?

面试题/03数据库中间件/06MQ/01Kafka/Kafka如何保证消息不丢失?.md

面试记录 2026-09-22

题目:Kafka 如何保证消息不丢失?

难度:medium

标签:db/mq/kafka, mq/kafka, general/knowledge, difficulty/medium

评分:⭐⭐⭐☆☆(3/5)

我的回答

Kafka 保持保证消息不丢失,要确保消息不丢失,首先要从三个端去考虑。首先是生产者,生产者端发送消息的时候,要明确能发到 Broker 管理端,也就是说这条消息发送出去,要通过管理端 Broker 的确认,确认告知这条消息已经发出了,才能确认这条消息发出了生产者端。然后其次到 Broker Broker 的时候进行落盘,把这条消息落到磁盘中,明确确保这条消息落在本地,通过持久化顺序写,保证消息的消息确认保存下来,确保这个消息已经不会再丢失,持久化的落到本地。第三在消费者端,消费者消费这条消息的时候,明确的告知生 Broker 这条消息我消费了,并且消费成功了,确保整个消息链路每个节点都知道自己的结果,最终实现整个消息不丢失。然后对应的在消费者上应该会有重试,如果消费出现问题可以重试,然后生产者如果出现问题要重发,大概是这么个机制。

点评

优点:

不足:

补充(必须掌握的关键参数):

Producer 端:

Broker 端:

Consumer 端:

完整讲解

第一部分:知识重点剖析

核心考点定位:考察是否能分层次、带参数地回答 Kafka 消息可靠性,涉及"至少一次"和"精确一次"两个语义层级。

知识点拆解:

  1. 语义基础:
  1. Producer 端防丢:
  1. Broker 端防丢:
  1. Consumer 端防丢:
  1. 端到端 Exactly-Once:
核心权衡:可靠性 vs 性能。ack=all + min.insync=2 + idempotence 会带来明显延迟,生产上需按业务分级。

第二部分:考察方向与延伸递进

考察方向:

延伸递进面试题:

  1. acks=all 但 ISR 只剩 1 个副本,会怎样?
  1. 为什么 Kafka 只能保证至少一次而不能保证精确一次?
  1. Kafka 事务消息和 RocketMQ 事务消息有什么区别?

第三部分:面试者参考回答(300-600 字口语化)

面试官您好,Kafka 保证消息不丢失需要按 Producer、Broker、Consumer 三段链路来设计,每一段都有对应的关键配置。

Producer 端有 4 个关键点:第一 acks=all,让 Producer 等所有 ISR 副本确认才返回;第二 retries 设置为最大,网络异常自动重试;第三 enable.idempotence=true 开启幂等,防止 Producer 崩溃重启后重复发送,这是靠 transactional.id 生成 PID 实现的;第四 max.in.flight.requests.per.connection=5,幂等允许的最大值,超过会乱序。

Broker 端主要是副本配置:replication.factor=3 保证 3 副本,min.insync.replicas=2 保证至少 2 副本确认才返回成功,unclean.leader.election.enable=false 不允许非 ISR 副本当 Leader,避免数据丢失。刷盘策略一般依赖 OS Page Cache,不主动 fsync。

Consumer 端最关键的是 enable.auto.commit=false 关闭自动提交,业务处理成功后再手动 commitSync,防止处理失败但 offset 已经提交的场景。同时消费端要做幂等——数据库唯一索引、Redis 记录、去重表都可以。

需要澄清一个概念:Kafka 只能保证至少一次,不能保证精确一次。要实现端到端 Exactly-Once,需要 Producer 幂等 + Broker 副本可靠 + Consumer 事务配合(transactional.id + isolation.level=read_committed),并且外部存储也要用事务或唯一约束配合。

生产上一般按业务分级:重要业务用严格配置(acks=all + min.insync=2 + idempotence),普通业务可以适当放宽以换取性能。同时要监控 ISR 收缩告警,防止 ISR 只剩 1 个副本时 Producer 阻塞。