确认topic分区是否处于underreplicated状态,需执行kafka-topics.sh --describe --topic 命令,检查各分区isr列表是否少于replicationfactor;若isr数量不足(如副本数为3而isr仅[1,2]),即为underreplicated分区。

怎么确认Topic分区是否真的处于UnderReplicatedPartitions状态
直接查 kafka-topics.sh 或 kafka-broker-api 返回的 UnderReplicatedPartitions 数值只是个汇总指标,它不告诉你具体是哪个分区、哪台Broker掉队了。真正要定位问题,得看每个分区的 ISR(In-Sync Replicas)列表是否完整。
执行以下命令获取指定Topic所有分区的详细副本状态:
kafka-topics.sh --bootstrap-server localhost:9092 --describe --topic <your-topic-name></your-topic-name>
重点关注输出中 Isr 列——如果某分区的 Isr 数量少于 ReplicationFactor(比如副本数设为3,但 Isr 只有 [1,2]),这个分区就属于 UnderReplicated。
-
Leader字段显示当前主副本所在Broker ID,若该Broker频繁切换或不可达,会拖累ISR更新 -
Replicas是静态配置的副本集合,Isr是动态维护的“已同步”子集,二者不一致才是问题信号 - 注意区分
OfflinePartitionsCount(完全离线)和UnderReplicatedPartitions(还在运行但同步滞后)
为什么ISR收缩但没恢复:常见底层原因
ISR 不是靠心跳维持的,而是依赖 follower 副本能否在 replica.lag.time.max.ms(默认10秒)内追上 leader 的 LEO(Log End Offset)。超时即被踢出 ISR,而恢复需要 follower 主动拉取并完成追赶。
典型卡点包括:
-
replica.fetch.wait.max.ms过小(如设为100ms),导致 follower 频繁空轮询,无法积攒批量数据,吞吐下降,追赶变慢 - Broker 磁盘 I/O 压力大(
disk IO wait > 20%),follower 写日志延迟高,LEO 追不上 leader - 网络分区或跨机房带宽不足,follower fetch 请求 RTT 超过
replica.lag.time.max.ms - Leader 所在 Broker CPU 持续 >90%,影响 replica fetch 响应速度,间接导致 follower 被踢出 ISR
如何快速验证某个Broker是否拖慢了ISR同步
不用等自动恢复,直接查该Broker上所有 follower 副本的同步延迟:
kafka-run-class.sh kafka.tools.ReplicaVerificationTool --broker-list localhost:9092 --topic-white-list ".*" --max-messages 1
更轻量的方式是查 JMX 指标(需开启 JMX):
-
kafka.server:type=FetcherLagMetrics,name=ConsumerLag,clientId=replica-fetcher-<broker-id>,topic=<topic>,partition=<id></id></topic></broker-id>—— lag 值持续 >0 且增长,说明该 follower 落后 -
kafka.server:type=ReplicaManager,name=IsrShrinksPerSec和IsrExpandsPerSec对比:若 shrink 高但 expand 几乎为0,说明 follower 卡死,无法重新加入 ISR - 检查
kafka.network:type=RequestMetrics,name=RequestsPerSec,request=FETCH在 follower Broker 上是否显著低于 leader
注意:JMX 中的 ConsumerLag 是 follower 当前 offset 与 leader LEO 的差值,不是 consumer group 的 lag。
调整参数前必须核对的三个前提
别一上来就调大 replica.lag.time.max.ms,这只会掩盖问题,而不是解决同步瓶颈:
- 确认磁盘没有满(
df -h /var/log/kafka)、inode 未耗尽(df -i),否则 follower 写入失败,ISR 永远无法恢复 - 检查
log.dirs配置路径下是否有大量.deleted或.cleaning临时文件堆积,可能阻塞日志滚动 - 确认
num.replica.fetchers(默认1)是否足够:当单Broker承载数百个 follower 分区时,一个 fetcher 线程容易成为瓶颈,可适当调至2或3
真正难处理的是跨机房同步场景——即使网络 RTT 稳定在80ms,只要 replica.lag.time.max.ms 小于 2×RTT + 处理开销,就可能误踢。这时候得结合 replica.fetch.response.max.bytes 和批量大小一起调优,而不是单独拉长超时。











