Kafka 副本同步:理解 ISR 与 AR
Kafka 靠副本机制保证高可用和数据一致性,其中 ISR 和 AR 是绕不开的两个概念。AR 是分配的所有副本,ISR 是与 Leader 保持同步的副本集合。搞清它们在什么情况下变动、如何影响消息可靠性,对线上运维很重要。
AR 与 ISR 的基本定义
AR(Assigned Replicas)就是分区的全部副本,Leader 和所有 Follower 都算。比如一个分区有 5 个副本,[0,1,2,3,4],那么 AR 就是这个集合。
ISR(In-Sync Replicas)则是与 Leader 同步的副本子集,Leader 自身始终在 ISR 里。Follower 同步正常就在 ISR,落后了就被移出去。比如 ISR 可能是 [0,1,2,3],意味着副本 4 没跟上。
把落后副本单独称为 OSR(Out-of-Sync Replicas),自然有:AR = ISR ∪ OSR,两者不重叠。
怎么判断 Follower 是否在 ISR 里?
Kafka 不只看消息落后多少条,而是看时间差。核心参数是 replica.lag.time.max.ms,默认 30 秒。如果一个 Follower 在过去 30 秒内都没有拉取过消息,它会被踢出 ISR。
源码里类似这样的逻辑:
// 概念性代码
def isInSync(replica: Replica): Boolean = {
val lastCaughtUpTimeMs = replica.lastCaughtUpTimeMs
val currentTimeMs = time.milliseconds()
(currentTimeMs - lastCaughtUpTimeMs) <= config.replicaLagTimeMaxMs
}
注意,即使 Follower 落后了很多消息,只要它还在持续拉取,就仍在 ISR 中;只有长时间不拉取才会被移出去。所以别把这个机制误解成基于落后条数的。
相关 Broker 配置
# 时间阈值
replica.lag.time.max.ms=30000
# 最小同步副本数(也可在 topic 级别设置)
min.insync.replicas=2
# 是否允许从 OSR 中选 Leader(脏选举)
unclean.leader.election.enable=false
ISR 的核心作用
Leader 选举
当 Leader 宕机,Controller 会从 ISR 中选一个新 Leader。这么做是因为 ISR 里的副本数据与旧 Leader 基本一致,选出来不会丢数据。
如果 ISR 清空了怎么办?这就涉及 unclean.leader.election.enable。如果设为 true,Kafka 会从 OSR(落后副本)里挑一个当 Leader,这可能丢数据,是拿一致性换可用性的操作。生产环境一般设为 false。
消息确认的基准
生产者的 acks 参数直接决定对 ISR 的依赖程度:
acks=0:不等待确认,可能丢数据,性能最高。acks=1:Leader 写入成功即返回,不保证 Follower 同步。acks=all(或-1):需要 ISR 中至少min.insync.replicas个副本确认才算成功。这是最安全的配置。
一般高可靠场景用 acks=all 并配合 min.insync.replicas 大于 1,确保至少多个副本都写入了。如果 ISR 数量少于 min.insync.replicas,生产者会收到 NotEnoughReplicasException。
示例配置:
Properties props = new Properties();
props.put(, );
props.put(, Integer.MAX_VALUE);
props.put(, );
props.put(, );


