3节点Kafka集群报NotLeader/副本不足错误导致数据丢失咨询
集群配置问题判定
现有日志和主题元数据已经明确证明集群配置存在根本性错误,完全不满足3节点集群的可靠性要求,所有异常均由配置错误直接导致。
核心错误点
- 所有主题(包括Kafka内置位移主题
__consumer_offsets、Kafka Connect依赖的connect-configs/connect-offsets/connect-status三个内部主题、所有业务主题)的副本因子全部为1,每个分区仅存储在单个Broker上,完全没有数据冗余,分布式集群的高可用能力完全失效。 - 配置的
min.insync.replicas=2与副本因子=1的规则存在本质冲突,这就是NotEnoughReplicasException报错的直接原因:每个分区的ISR集合里只有1个副本,永远无法满足ISR最少2个副本的写入要求,消息写入会直接被拒绝。 - 日志中的
NotLeaderOrFollowerException告警是单副本场景下的典型异常:当Broker短暂重启、分区发生切主时,客户端缓存的旧Leader信息失效,请求打到非Leader副本就会触发该报错,切主期间生产、消费请求都会短暂失败。
数据异常的直接原因
- 部分表无数据写入:单副本配置下,只要承载对应分区的Broker出现进程闪断、磁盘故障、网络波动,该分区就会完全不可用,写入请求直接失败;叠加min.isr配置冲突,大量写入请求被Broker拒绝,Connect任务无法正常同步数据。
- 冗余重复记录:Connect存储消费位移、任务状态的内部主题全是单副本,只要对应分区所在Broker不可用,Connect就无法正常提交消费位移,任务恢复后会从上一次成功提交的位移位置重新拉取数据,写入目标端就会产生重复;如果生产者未开启幂等性,请求重试时也会产生重复写入。
修复方案
1. 调整集群默认配置,避免后续新增主题出现同类问题
修改3个Broker的server.properties配置文件,调整以下参数:
default.replication.factor=3:默认新建主题的副本因子设为3,匹配3节点集群规模min.insync.replicas=2:该参数无需修改,3副本场景下配置min.isr=2是可靠性与可用性的最优组合,允许单节点宕机不影响服务auto.create.topics.enable=false:关闭自动创建主题功能,避免自动生成的主题副本配置不符合要求
同时修改Kafka Connect的Worker配置文件,开启幂等生产与事务提交,从机制上避免重复写入:producer.enable.idempotence=trueconsumer.enable.auto.commit=false- 为Connect配置集群唯一的
transactional.id参数,启用事务提交位移与同步数据的能力
2. 修复现有主题的副本配置
对所有已存在的主题执行分区副本重分配,将所有分区的副本数调整为3,步骤如下:
- 创建文件
all-topics.json,写入要调整的主题列表,覆盖所有内置主题、Connect内部主题、业务主题 - 执行命令生成重分配计划:
kafka-reassign-partitions.sh --bootstrap-server <Broker连接地址,格式为ip1:9092,ip2:9092,ip3:9092> --generate --topics-to-move-json-file all-topics.json --broker-list "0,1,2" - 执行生成的重分配计划,等待副本同步完成:
kafka-reassign-partitions.sh --bootstrap-server <Broker连接地址> --execute --reassignment-json-file <上一步生成的重分配计划文件路径> - 同步完成后执行
kafka-topics.sh --describe验证,确认所有分区的Replicas列表包含0、1、2三个Broker,ISR列表同步完成后也包含三个节点。
注意:__consumer_offsets和三个Connect内部主题必须纳入重分配范围,这几个主题存储了所有消费位移、Connect任务配置与状态,是之前故障的核心诱因
3. 紧急恢复与验证
- 副本重分配期间如果需要紧急恢复业务,可以临时将报错分区的
min.insync.replicas调整为1先恢复写入,但这只是临时降级方案,必须等副本数调整完成后改回2,否则可靠性无保障。 - 所有副本同步完成后,重启Kafka Connect集群,观察日志:
NotEnoughReplicasException错误会完全消失,偶发的NotLeaderOrFollowerException属于正常切主重试告警,只要重试后能恢复无需额外处理。 - 修复后验证目标端数据:无数据写入的问题会直接解决,重复数据问题会随着幂等生产者、事务提交的启用消除,历史产生的重复数据可单独做一次去重清理。
3节点Kafka集群的核心主题必须配置3副本、min.insync.replicas=2,才能实现单节点故障不丢数、不中断服务的可靠性目标。之前的配置本质是把分布式集群拆成了3个独立的单节点使用,完全没有用到分布式集群的冗余能力,仅靠监控无法规避配置错误导致的故障。
内容的提问来源于stack exchange,提问作者Austin Jackson
相关产品推荐
相关产品推荐

