acks是 Kafka 生产者最核心的可靠性配置,它指定了生产者发送消息后,需要收到多少个 Broker 副本的写入确认,才认为消息发送成功。该参数直接决定了消息的可靠性和系统吞吐量,是 Kafka 数据不丢失保证的基石。
一、acks三个核心取值详解
1.acks=0(发后即忘,Fire-and-Forget)
工作原理
生产者发送消息后不等待任何 Broker 的确认,消息写入生产者本地缓冲区后立即返回成功。Broker 是否收到、是否写入磁盘,生产者完全不感知。
核心特点
- 吞吐量最高:完全无阻塞,TPS 可达数十万/秒,是性能最好的模式
- 可靠性最低:网络抖动、Broker 宕机、缓冲区满都会导致消息永久丢失,且无法重试
- 延迟最低:几乎没有等待时间
适用场景
仅用于允许少量消息丢失的非核心场景:
- 应用日志、访问日志收集
- 用户行为埋点、页面点击统计
- 非关键监控指标上报
2.acks=1(Leader 确认,默认值)
工作原理
生产者发送消息后,只需要等待分区的 Leader 副本写入成功并返回确认,就认为消息发送成功。不需要等待 Follower 副本同步数据。
核心特点
- 平衡性能与可靠性:是 Kafka 的默认配置,适合绝大多数普通业务
- 存在数据丢失风险:如果 Leader 写入成功后,在 Follower 同步完成之前突然宕机,且新选举的 Leader 没有这条消息,数据会永久丢失
- 吞吐量中等:比
acks=0低,但远高于acks=all
适用场景
普通业务场景,允许极低概率的数据丢失:
- 订单状态通知、库存变更通知
- 非核心数据同步
- 一般的消息推送
3.acks=all/acks=-1(ISR 全部确认,最高可靠性)
工作原理
生产者发送消息后,需要等待 ISR(In-Sync Replicas,同步副本集合)中的所有副本都写入成功并返回确认,才认为消息发送成功。
核心特点
- 可靠性最高:只要 ISR 中至少有一个副本存活,数据就不会丢失
- 吞吐量最低:需要等待所有副本同步完成,延迟最高
- 必须配合
min.insync.replicas配置:否则acks=all也可能丢数据(这是最常见的误区)
关键配套配置
| 配置项 | 作用 | 生产级建议值 |
|---|---|---|
min.insync.replicas | 指定 ISR 中至少需要有多少个副本处于同步状态,生产者才会认为发送成功 | 2(核心业务) |
unclean.leader.election.enable | 是否允许非 ISR 中的副本当选 Leader | false(必须关闭,禁止脏选举) |
⚠️ 重要说明:
- 如果
min.insync.replicas=1(默认值),那么acks=all只需要 Leader 确认,和acks=1效果完全一样,Leader 宕机仍会丢数据 - 生产环境核心业务必须设置
min.insync.replicas=2,确保至少 2 个副本同步成功 - 当 ISR 中的副本数小于
min.insync.replicas时,生产者会抛出NotEnoughReplicasException
适用场景
核心业务场景,绝对不允许数据丢失:
- 支付结果通知、交易流水记录
- 订单创建、资金变动
- 核心数据同步
二、acks取值对比速查表
acks取值 | 确认条件 | 可靠性 | 吞吐量 | 延迟 | 数据丢失风险 | 适用场景 |
|---|---|---|---|---|---|---|
0 | 无需任何确认 | 最低 | 最高 | 最低 | 极高 | 非核心数据(日志、埋点) |
1 | 仅 Leader 确认 | 中等 | 中等 | 中等 | 低 | 普通业务(通知、同步) |
all/-1 | ISR 所有副本确认 | 最高 | 最低 | 最高 | 极低(配合正确配置) | 核心业务(支付、交易) |
三、常见误区澄清
❌ 误区1:acks=all就绝对不会丢数据
纠正:只有同时满足以下三个条件,才能保证数据不丢失:
acks=allmin.insync.replicas≥2unclean.leader.election.enable=false
如果缺少任何一个条件,都存在数据丢失的可能。例如:
min.insync.replicas=1时,acks=all等同于acks=1- 开启脏选举时,非 ISR 副本当选 Leader 会导致已确认的消息丢失
❌ 误区2:acks=0一定会丢数据
纠正:acks=0只是不等待确认,在网络正常、Broker 稳定的情况下,消息仍然会被成功写入。它只是在异常场景下(如 Broker 突然宕机)无法保证数据不丢失。
❌ 误区3:开启幂等性会自动设置acks=1
纠正:开启幂等性生产者(enable.idempotence=true)后,Kafka 会自动将acks设置为all,以保证幂等性的正确性。如果需要使用acks=1,必须手动关闭幂等性,但不建议这么做(幂等性几乎没有性能开销)。
四、生产级最佳实践
核心业务(支付、交易、订单)
# 最高可靠性配置 spring.kafka.producer.acks=all spring.kafka.producer.properties.min.insync.replicas=2 spring.kafka.producer.properties.unclean.leader.election.enable=false spring.kafka.producer.enable-idempotence=true # 开启幂等性 spring.kafka.producer.retries=3普通业务(通知、同步、推送)
# 平衡性能与可靠性(默认配置) spring.kafka.producer.acks=1 spring.kafka.producer.enable-idempotence=true spring.kafka.producer.retries=3非核心业务(日志、埋点、监控)
# 最高性能配置 spring.kafka.producer.acks=0 spring.kafka.producer.retries=0 spring.kafka.producer.properties.linger.ms=5 # 开启批量发送通用建议
- 所有场景都建议开启幂等性生产者,避免重试导致的消息重复
- 不同主题可以根据业务重要性单独设置
acks值 - 监控生产者的发送成功率和重试次数,及时发现异常