Kafka生产者的 acks 参数(0, 1, -1/all)分别代表什么含义?
Kafka 生产者的 acks(acknowledgments)参数是 Kafka 中最关键的配置之一,它决定了生产者在发送消息后,需要等到多少个 Broker 确认收到消息,才算发送成功。
这个参数直接权衡了系统的数据可靠性(Durability)与吞吐量/延迟(Performance)。
以下是 0、1 和 -1 (all) 的详细含义及区别:
1. acks=0 (发后即忘 / Fire and Forget)
- 含义:生产者把消息发送出去后,完全不等待 Broker 的任何响应,直接认为发送成功。
- 工作机制:
- Producer 将消息写入网络缓冲区后立即返回成功。
- Broker 不需要回复确认(Ack)。
- 优点:
- 吞吐量最高。
- 延迟最低。
- 缺点:
- 数据丢失风险极高。如果 Broker 宕机、网络异常或者 Leader 选举期间,生产者完全不知道消息没送到,数据直接丢失。
- 适用场景:
- 允许丢失数据的场景,如日志收集、非核心指标监控数据。
2. acks=1 (Leader 确认 / Default in older versions)
- 含义:生产者发送消息后,只要 Leader 副本 成功写入本地日志,Broker 就会回复“发送成功”,不需要等待 Follower 副本同步。
- 工作机制:
- Leader 收到消息 -> 写入本地 Log -> 返回 Ack 给 Producer。
- Leader 不等待 Follower 同步数据。
- 优点:
- 性能和可靠性的折中方案。吞吐量尚可,比
acks=all快。
- 性能和可靠性的折中方案。吞吐量尚可,比
- 缺点:
- 存在数据丢失风险。如果 Leader 刚写入数据并回复了 Ack,但在 Follower 同步之前 Leader 挂掉了,这部分数据就会丢失(因为新的 Leader 没有这条数据)。
- 适用场景:
- 一般的业务日志、非强一致性要求的业务数据。
3. acks=-1 或 acks=all (ISR 全体确认 / Strongest Guarantee)
- 含义:生产者发送消息后,Leader 必须等待 ISR(In-Sync Replicas,同步副本列表)中所有副本 都成功写入日志后,才会回复“发送成功”。
- 工作机制:
- Leader 收到消息 -> 写入本地 Log -> 等待 ISR 列表中的 Followers 拉取并写入 Log -> Leader 收到所有 ISR 的确认 -> 返回 Ack 给 Producer。
- 优点:
- 数据可靠性最高。只要 ISR 中至少还有一个副本存活,数据就不会丢失。
- 缺点:
- 延迟最高(需要等待网络同步)。
- 吞吐量最低。
- 重要补充(min.insync.replicas):
acks=all必须配合 Broker 端的min.insync.replicas参数使用才有意义。- 如果
min.insync.replicas=1,即使acks=all,实际上也只等 Leader 写入就返回了(效果等同于acks=1)。 - 通常建议配置:
replication.factor = 3,min.insync.replicas = 2,acks = all。这意味着至少要有 2 个副本写入成功,才算发送成功。
- 适用场景:
- 金融交易、订单数据、账户余额等绝对不允许丢数据的核心场景。
总结对比表
| 参数值 | 确认机制 | 可靠性 | 吞吐量 | 延迟 | 数据丢失风险 |
|---|---|---|---|---|---|
| 0 | 不等待任何确认 | 最低 | 最高 | 最低 | 极高 (Broker 挂了完全不知情) |
| 1 | 仅等待 Leader 写入 | 中等 | 中等 | 中等 | 中等 (Leader 挂了且未同步时丢失) |
| -1 / all | 等待 ISR 所有副本写入 | 最高 | 最低 | 最高 | 极低 (除非 ISR 全部同时挂掉) |
最佳实践建议
- Kafka 3.0+ 版本:默认值已经改为
acks=all,以优先保证数据安全。 - 开发建议:除非你有极其严苛的性能要求且允许丢数据,否则建议在生产环境至少使用
acks=1;对于核心业务,务必使用acks=all并配合min.insync.replicas >= 2。
右滑查看面试常问