You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

配置min.insync.replicas=2和acks=all,Kafka仍丢数据?

Kafka数据丢失疑问:min.insync.replicas=2+acks=all配置下的异常场景

3节点Kafka集群(版本2.6.3),配置min.insync.replicas=2和acks=all,测试过程中出现数据丢失,核心疑问:开启unclean leader选举后,为何没有选择数据更新的副本作为Leader,反而出现数据丢失?


一、环境准备

设置环境变量:

export BOOTSTRAP_SERVERS=kafka171:9092,kafka172:9092,kafka173:9092
export TOPIC_NAME=playground__dummy_test
export ZOOKEEPER_CONNECT=zk:2181/kafka_123

创建Topic:

$ kafka-topics.sh --zookeeper $ZOOKEEPER_CONNECT --topic $TOPIC_NAME --create --partitions 1 --replication-factor 3

查看Topic初始信息:

$ kafka-topics.sh --zookeeper $ZOOKEEPER_CONNECT --describe --topic $TOPIC_NAME

Topic: playground__dummy_test   Partition: 0    Leader: 171 Replicas: 171,172,173   Isr: 171,172,173

二、测试流程

1. 生产初始消息

启动控制台生产者(指定acks=all):

$ kafka-console-producer.sh --broker-list $BOOTSTRAP_SERVERS --topic $TOPIC_NAME --request-required-acks all
> I am writing to all 3 of you

2. 关闭Broker 171

继续生产消息,此时Topic状态更新:

>everything should be fine now
>there is 171 broker down

Topic: playground__dummy_test   Partition: 0    Leader: 172 Replicas: 171,172,173   Isr: 173,172

> all I am writing is in 172,173

3. 关闭Broker 172

此时ISR仅剩余1个副本,生产消息触发异常(符合min.insync.replicas=2的配置预期):

Topic: playground__dummy_test   Partition: 0    Leader: 173 Replicas: 171,172,173   Isr: 173

> hey
NotEnoughReplicasException: Messages are rejected since there are fewer in-sync replicas than required.

4. 全Broker离线后重启部分节点

  • 关闭Broker 173,此时3个Broker均离线
  • 启动Broker 171,查看Topic状态:
Topic: playground__dummy_test   Partition: 0    Leader: -1  Replicas: 171,172,173   Isr: 173
  • 启动Broker 172,因unclean.leader.election.enable=false,集群仍无Leader:
Topic: playground__dummy_test   Partition: 0    Leader: -1  Replicas: 171,172,173   Isr: 173

当前运行的171、172两个Broker中,172存储了后续通过acks=all写入的最新数据,但173已永久故障无法恢复。

5. 开启unclean leader选举并观察结果

查询当前Controller的Broker ID:

$ CONTROLLER_ID=`/opt/kafka/bin/zookeeper-shell.sh $ZOOKEEPER_CONNECT get /controller | grep brokerid | jq '.brokerid'`

在Controller上开启unclean leader选举:

$ kafka-configs.sh --bootstrap-server $BOOTSTRAP_SERVERS --entity-type brokers --entity-name $CONTROLLER_ID --alter --add-config unclean.leader.election.enable=true 
Completed updating config for broker: 171.

查看Topic状态,发现171被选为Leader:

$ kafka-topics.sh --zookeeper $ZOOKEEPER_CONNECT --describe --topic $TOPIC_NAME
Topic: playground__dummy_test   Partition: 0    Leader: 171 Replicas: 171,172,173   Isr: 171,172
-> 触发了Leader选举

消费消息时,仅能读取到第一条初始消息,后续写入的消息全部丢失:

$ kafka-console-consumer.sh --bootstrap-server $BOOTSTRAP_SERVERS --topic $TOPIC_NAME --from-beginning
I am writing to all 3 of you

核心疑问

开启unclean leader选举后,为何没有选择数据更新的172副本作为Leader,反而选择了数据最旧的171,导致后续写入的消息全部丢失?


内容的提问来源于stack exchange,提问作者remigiusz boguszewicz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 11:41:02