10.1.6 ACK机制与ISR一致性

ACK机制与ISR一致性#

ACK机制决定生产者写入是否视为成功,ISR(In-Sync Replicas)决定可参与确认的副本集合。本节通过原理图、配置、命令、示例与排错帮助你在一致性与可用性之间做出可控选择。

原理草图(ACK与ISR协作)#

文章图片

1. ACK级别与语义(含示例)#

  • acks=0:不等响应,高吞吐低延迟,可能丢消息。
  • acks=1:Leader写入即成功,Follower异步复制,Leader宕机可能丢确认消息。
  • acks=all(-1):ISR内副本写入完成后确认,可靠性高但延迟增加。

生产者示例:不同ACK级别

# 生产者直连,分别测试 acks=0/1/all
bin/kafka-console-producer.sh \
  --bootstrap-server 127.0.0.1:9092 \
  --topic ack-demo \
  --producer-property acks=all \
  --producer-property linger.ms=5 \
  --producer-property batch.size=32768

# 预期效果:acks=all 时延迟略高,但生产失败会有错误提示

2. ISR定义与维护(关键参数+配置示例)#

关键参数说明
- replica.lag.time.max.ms:Follower超过该时间未拉取则移出ISR。
- min.insync.replicas:要求至少多少ISR副本确认写入。

安装/配置(以单机演示为例,修改Broker配置)

# 1) 修改 Broker 配置
sudo vi /opt/kafka/config/server.properties

# 2) 追加或修改参数
# 副本与ISR相关
default.replication.factor=3
min.insync.replicas=2
replica.lag.time.max.ms=10000

# 3) 重启 Kafka(systemd 或脚本方式)
sudo systemctl restart kafka

# 预期效果:当ISR少于2时,acks=all写入失败

3. ACK与ISR一致性关系(示例与可验证操作)#

创建主题并验证

# 创建3副本主题
bin/kafka-topics.sh --bootstrap-server 127.0.0.1:9092 \
  --create --topic ack-demo --partitions 3 --replication-factor 3

# 查看ISR状态
bin/kafka-topics.sh --bootstrap-server 127.0.0.1:9092 \
  --describe --topic ack-demo

# 预期效果:每个分区的 ISR 应包含 3 个副本

模拟ISR不足导致写入失败(需要停掉一个Broker)

# 假设有3个Broker,停掉其中两个,导致ISR<2
sudo systemctl stop kafka@2
sudo systemctl stop kafka@3

# 使用 acks=all 发送消息
bin/kafka-console-producer.sh --bootstrap-server 127.0.0.1:9092 \
  --topic ack-demo --producer-property acks=all

# 预期效果:出现 NOT_ENOUGH_REPLICAS 或类似错误

4. 幂等生产者与ACK机制(配置示例)#

# /opt/kafka/config/producer.properties
bootstrap.servers=127.0.0.1:9092
acks=all
enable.idempotence=true
retries=10
request.timeout.ms=30000
delivery.timeout.ms=120000
# 使用配置文件发送
bin/kafka-console-producer.sh \
  --bootstrap-server 127.0.0.1:9092 \
  --topic ack-demo \
  --producer.config /opt/kafka/config/producer.properties

# 预期效果:网络抖动重试时不会产生重复消息

5. 常见问题与排查命令#

问题1:写入失败(NOT_ENOUGH_REPLICAS)

# 查看ISR是否不足
bin/kafka-topics.sh --bootstrap-server 127.0.0.1:9092 \
  --describe --topic ack-demo

# 查看Broker日志(路径可能不同)
tail -f /opt/kafka/logs/server.log

解释:若ISR数量小于 min.insync.replicas,acks=all会拒绝写入。

问题2:写入延迟高

# 查看磁盘IO与网络RTT
iostat -x 1
ping -c 5 broker2

# 调整批量参数(减小往返影响)
# linger.ms / batch.size 可减少请求次数

问题3:ISR频繁变动

# 查看副本落后与移出ISR日志
grep -i "ISR" /opt/kafka/logs/server.log | tail -n 50

6. 练习题(含目标与验证)#

1) 练习:验证min.insync.replicas
- 目标:设置 min.insync.replicas=2,停掉1个Broker后仍可写入,停掉2个后写入失败。
- 验证命令:

bin/kafka-topics.sh --bootstrap-server 127.0.0.1:9092 --describe --topic ack-demo

2) 练习:对比acks=1与acks=all延迟
- 目标:分别发送1000条消息,观察Producer端耗时差异。
- 验证命令:

time seq 1 1000 | \
  bin/kafka-console-producer.sh --bootstrap-server 127.0.0.1:9092 \
  --topic ack-demo --producer-property acks=1

time seq 1 1000 | \
  bin/kafka-console-producer.sh --bootstrap-server 127.0.0.1:9092 \
  --topic ack-demo --producer-property acks=all

通过ACK与ISR的协作机制配置、验证与排错,可在可靠性与性能之间建立可度量的平衡策略。