配置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
相关产品推荐
相关产品推荐

