Kafka控制台消费者卡顿求助:NotEnoughReplicasException异常
Kafka消费者卡顿+NotEnoughReplicasException异常分析与解决
先还原下你的问题场景:
你搭建了包含3个Broker的Kafka集群,创建了单分区、副本因子为1的主题new_topic,通过控制台生产者推送消息后,发现消费者消费出现卡顿。后续排查发现其中一个Broker(Broker2)抛出大量NotEnoughReplicasException异常,相关日志和主题信息如下:
异常日志
[2020-06-19 17:36:24,249] INFO [GroupCoordinator 2]: 准备重新平衡处于PreparingRebalance状态的组console-consumer-28937,旧版本号4822(__consumer_offsets-10)(原因:SyncGroup期间存储组分配时出错(成员:consumer-console-))(kafka.coordinator.group.GroupCoordinator) [2020-06-19 17:36:24,305] INFO [GroupCoordinator 2]: 稳定组console-consumer-28937,版本号4823(__consumer_offsets-10)(kafka.coordinator.group.GroupCoordinator) [2020-06-19 17:36:24,306] ERROR [ReplicaManager broker=2] 处理分区__consumer_offsets-10的追加操作时出错(kafka.server.ReplicaManager) org.apache.kafka.common.errors.NotEnoughReplicasException: 当前ISR集合大小(2)无法满足分区__consumer_offsets-10的min.isr要求(2) [2020-06-19 17:36:24,307] INFO [GroupCoordinator 2]: 准备重新平衡处于PreparingRebalance状态的组console-consumer-28937,旧版本号4823(__consumer_offsets-10)(原因:SyncGroup期间存储组分配时出错(成员:consumer-console-consumer-28937-1-21df21a9-3e11-4286-8252-3871633cf3bd))(kafka.coordinator.group.GroupCoordinator) [2020-06-19 17:36:24,349] INFO [GroupCoordinator 2]: 稳定组console-consumer-28937,版本号4824(__consumer_offsets-10)(kafka.coordinator.group.GroupCoordinator) [2020-06-19 17:36:24,351] INFO [GroupCoordinator 2]: 收到组console-consumer-28937版本号48的领导者分配信息 [2020-06-19 17:36:24,351] ERROR [ReplicaManager broker=2] 处理分区__consumer_offsets-10的追加操作时出错(kafka.server.ReplicaManager)
主题new_topic信息
Topic: new_topic PartitionCount: 1 ReplicationFactor: 1 Configs: Topic: new_topic Partition: 0 Leader: 3 Replicas: 3 Isr: 3
问题根源分析
你遇到的消费卡顿和异常其实是连锁反应,核心问题不在new_topic(这个主题单副本且运行正常),而是Kafka内置的消费者偏移量主题__consumer_offsets-10出了问题:
__consumer_offsets是Kafka用来存储消费者组偏移量的内置主题,消费者每次消费后会把偏移量写入这个主题,确保重启后能从正确位置继续消费。- 日志里的
NotEnoughReplicasException明确指出:__consumer_offsets-10的ISR(同步副本集合)大小为2,但它的min.isr(最小同步副本数)要求也是2。这种情况下,只要ISR里有任何一个副本出现同步延迟、网络中断或者Broker故障,就会导致可用的同步副本数不足,无法写入偏移量。 - 偏移量写入失败会触发消费者组不断重新平衡(日志里反复出现GroupCoordinator的重新平衡日志),消费者在重新平衡过程中无法正常消费,就表现为卡顿。
而Broker2出现大量异常处理,大概率是这个Broker的磁盘IO过高、网络连接异常,或者与其他Broker的副本同步出现问题,导致它从__consumer_offsets-10的ISR中被移除,进而引发连锁问题。
解决方案
1. 先排查异常Broker(Broker2)的状态
这是最根本的修复步骤:
- 用
df -h检查Broker2的磁盘空间是否充足,用iostat -x 1查看磁盘IO是否过高(如果磁盘读写负载长期超过80%,会严重影响副本同步)。 - 测试Broker2与其他Broker的网络连通性,比如用
ping <其他BrokerIP>和telnet <其他BrokerIP> 9092(默认Kafka端口)确认网络没有中断。 - 查看Broker2的完整Kafka日志,看看是否有磁盘错误、GC超时、内存不足等其他异常信息,这些都可能导致副本同步失败。
2. 临时缓解消费卡顿问题
如果Broker2短时间内无法恢复,可以先做临时调整让消费者正常工作:
- 临时降低
__consumer_offsets-10的min.isr(注意:这会牺牲数据可靠性,仅作为应急方案):# ZooKeeper模式 kafka-configs.sh --zookeeper <你的ZK地址> --entity-type topics --entity-name __consumer_offsets --alter --add-config min.insync.replicas=1 # KRaft模式(如果是新版Kafka) kafka-configs.sh --bootstrap-server <你的Broker地址> --entity-type topics --entity-name __consumer_offsets --alter --add-config min.insync.replicas=1 - 手动切换
__consumer_offsets-10的Leader到正常Broker:
这个命令会把该分区的Leader切换到首选Broker(通常是配置里的第一个副本),避免异常Broker处理该分区的请求。kafka-leader-election.sh --bootstrap-server <你的Broker地址> --topic __consumer_offsets --partition 10 --election-type preferred
3. 长期修复与预防
- 确保
__consumer_offsets的副本因子与集群规模匹配:3个Broker的集群,__consumer_offsets的副本因子应该设为3,这样即使一个Broker故障,还有两个副本可用。如果当前副本因子不足,可以用分区重分配工具调整:- 创建
reassignment.json文件:{ "version": 1, "partitions": [ {"topic": "__consumer_offsets", "partition": 10, "replicas": [1,2,3], "log_dirs": ["any", "any", "any"]} ] } - 执行重分配:
# ZooKeeper模式 kafka-reassign-partitions.sh --zookeeper <你的ZK地址> --reassignment-json-file reassignment.json --execute # KRaft模式 kafka-reassign-partitions.sh --bootstrap-server <你的Broker地址> --reassignment-json-file reassignment.json --execute
- 创建
- 合理配置
min.insync.replicas:在server.properties中设置集群默认的min.insync.replicas,3个Broker的场景下,默认设为2是比较均衡的选择(兼顾可靠性和可用性);如果业务对可用性要求更高,可以设为1,但要接受可能的数据丢失风险。 - 考虑开启
unclean.leader.election.enable:如果你的业务能接受少量数据丢失,可以把这个配置设为true,这样当ISR不足时,Kafka会允许非ISR中的副本成为Leader,避免出现无法写入的情况,但这会有数据丢失的风险,需要谨慎选择。
内容的提问来源于stack exchange,提问作者Nag
相关产品推荐
相关产品推荐

