Kafka ISR 与 AR 深度解析:副本同步机制核心概念
Kafka ISR 与 AR 深度解析:副本同步机制核心概念 在 Kafka 的分布式架构中,副本机制是保证高可用和数据一致性的基石。而 **ISR(In-Sync Replicas)** 和 **AR(Assigned Replicas)** 则是理解副本同步机制的两个核心概念。 今天,我们将深入剖析这两个概念的本质、作用以及它们在 Kafka 高可用架构中的关键地位。 一、核心概念定义 1.1…

Kafka ISR 与 AR 深度解析:副本同步机制核心概念 在 Kafka 的分布式架构中,副本机制是保证高可用和数据一致性的基石。而 **ISR(In-Sync Replicas)** 和 **AR(Assigned Replicas)** 则是理解副本同步机制的两个核心概念。 今天,我们将深入剖析这两个概念的本质、作用以及它们在 Kafka 高可用架构中的关键地位。 一、核心概念定义 1.1…

在 Kafka 的分布式架构中,副本机制是保证高可用和数据一致性的基石。而 ISR(In-Sync Replicas) 和 AR(Assigned Replicas) 则是理解副本同步机制的两个核心概念。
今天,我们将深入剖析这两个概念的本质、作用以及它们在 Kafka 高可用架构中的关键地位。
AR(Assigned Replicas):一个分区分配的所有副本集合,包括 Leader 和所有 Follower。
| 组件 | 说明 |
|---|---|
| Leader 副本 | 负责读写 |
| Follower 副本 | 同步数据 |
| AR 集合 | Leader + 所有 Follower |
ISR(In-Sync Replicas):与 Leader 保持同步的 Follower 集合,包括 Leader 自身。只有 ISR 中的副本才有资格被选举为新的 Leader。
| 状态 | 说明 |
|---|---|
| ISR 动态集合 | 与 Leader 同步的副本 |
| AR 集合 | 分配的所有副本 |
| Leader | 始终在 ISR 中 |
| Follower (正常) | 同步正常,在 ISR 中 |
| Follower (落后) | 同步落后,不在 ISR 中 |
| 概念 | 全称 | 定义 | 包含 |
|---|---|---|---|
| AR | Assigned Replicas | 分区分配的所有副本 | Leader + 所有 Follower |
| ISR | In-Sync Replicas | 与 Leader 保持同步的副本 | Leader + 同步的 Follower |
// Kafka 源码中的判断逻辑(概念性)
class ReplicaManager {
def isInSync(replica: Replica): Boolean = {
// 1. 必须是 Follower(或 Leader)
// 2. 必须与 Leader 保持同步
// 主要判断依据:
// - Follower 的 LEO(Log End Offset)要接近 Leader 的 LEO
// - Follower 的拉取请求要及时
// - 在 replica.lag.time.max.ms 时间内有拉取请求
val maxLagMs = config.replicaLagTimeMaxMs
val lastCaughtUpTimeMs = replica.lastCaughtUpTimeMs
val currentTimeMs = time.milliseconds()
// 如果最后一次追上 Leader 的时间在允许范围内
(currentTimeMs - lastCaughtUpTimeMs) <= maxLagMs
}
}
# Kafka Broker 配置
# 1. 副本落后最大时间阈值
replica.lag.time.max.ms=30000
# 默认 30 秒
# 如果 Follower 超过 30 秒没有拉取消息,就会被踢出 ISR
# 2. 最小同步副本数
min.insync.replicas=2
# Topic 级别或 Broker 级别配置
# 生产者在 acks=all 时需要 ISR 中至少有这么多个副本
Kafka ISR (In-Sync Replicas) 动态变化过程如下:
Kafka Leader 选举流程:
选举规则:
特殊情况:
unclean.leader.election为什么只能用 ISR 选举?
// Producer 的 acks 参数
Properties props = new Properties();
// acks=0:不等待确认,可能丢数据,性能最高
props.put("acks", "0");
// acks=1:Leader 确认即可,Leader 写入成功就返回
props.put("acks", "1");
// acks=all:ISR 全部确认,最安全,性能最低
// 或 acks=-1(等同于 all)
props.put("acks", "-1");
acks=all 的工作原理:
// 结合 min.insync.replicas 保证最小同步数
// Topic 配置
bin/kafka-topics.sh \
--bootstrap-server localhost:9092 \
--alter \
--topic my-topic \
--config min.insync.replicas=2
// Producer 配置
props.put("acks", "all"); // 要求所有 ISR 确认
// 当 ISR 数量小于 min.insync.replicas 时
// 比如:副本数=3,ISR=[0,1](2 个),min.insync.replicas=2 ✅ 可用
// 如果 ISR=[0](1 个),min.insync.replicas=2 ❌ 不可用,Producer 会收到异常
AR = {Leader, Follower1, Follower2, Follower3, ...}
ISR = {Leader, Follower_i, Follower_j, ...} 其中 Follower 满足同步条件
OSR = AR - ISR # Out-of-Sync Replicas,同步落后的副本
AR = ISR ∪ OSR
ISR ∩ OSR = ∅
# 查看副本状态
bin/kafka-topics.sh \
--bootstrap-server localhost:9092 \
--describe \
--topic my-topic
# 输出示例
# Topic: my-topic Partition: 0 Leader: 0 Replicas: 0,1,2,3,4 Isr: 0,1,2,3
# AR: [0,1,2,3,4]
# ISR: [0,1,2,3]
# OSR: [4]
# server.properties
# Follower 落后多长时间被踢出 ISR(默认 30 秒)
replica.lag.time.max.ms=30000
# 是否允许不在 ISR 中的副本被选举为 Leader
# 如果设为 true,可能会丢数据;设为 false,提高数据一致性
unclean.leader.election.enable=false
# 最小同步副本数(也可在 Topic 级别设置)
min.insync.replicas=1
# 创建 Topic 时设置
bin/kafka-topics.sh \
--bootstrap-server localhost:9092 \
--create \
--topic my-topic \
--partitions 3 \
--replication-factor 3 \
--config min.insync.replicas=2
# 修改现有 Topic
bin/kafka-topics.sh \
--bootstrap-server localhost:9092 \
--alter \
--topic my-topic \
--config min.insync.replicas=2
// Producer 配置影响 ISR 的使用
Properties props = new Properties();
// 一致性要求高的场景
props.put("acks", "all"); // 等待所有 ISR 确认
props.put("retries", 3); // 重试次数
props.put("max.in.flight.requests.per.connection", 1); // 保证顺序
// 性能优先的场景
props.put("acks", "1"); // Leader 确认即可
props.put("retries", 0); // 不重试
// 当 Leader 宕机时,Kafka 的选举逻辑
public class LeaderElection {
public void electNewLeader(Partition partition) {
// 1. 获取当前 ISR 列表
List<Replica> isr = partition.getInSyncReplicas();
// 2. 优先从 ISR 中选举
if (!isr.isEmpty()) {
// 选择 ISR 中的第一个作为新 Leader
Replica newLeader = isr.get(0);
partition.setLeader(newLeader);
} else {
// 如果 ISR 为空,根据配置决定
if (uncleanLeaderElectionEnabled) {
// 允许从 OSR 中选举(可能丢数据)
Replica newLeader = chooseFromOSR();
partition.setLeader(newLeader);
} else {
// 不可用
throw new NoReplicaAvailableException();
}
}
}
}
// 需要高可靠性的生产者配置
public class ReliableProducer {
public static void main(String[] args) {
Properties props = new Properties();
props.put("bootstrap.servers", "localhost:9092");
props.put("acks", "all");
props.put("retries", Integer.MAX_VALUE);
props.put("max.in.flight.requests.per.connection", 1);
props.put("enable.idempotence", "true"); // 开启幂等性
// 还需要 Topic 配置 min.insync.replicas=2
KafkaProducer<String, String> producer = new KafkaProducer<>(props);
// 发送消息
producer.send(new ProducerRecord<>("my-topic", "key", "value"), (metadata, exception) -> {
if (exception != null) {
// 如果 ISR 不足,会收到 NotEnoughReplicasException
handleException(exception);
}
});
}
}
# 监控 ISR 收缩和扩张
bin/kafka-topics.sh \
--bootstrap-server localhost:9092 \
--describe \
--topic my-topic \
--under-replicated-partitions
# 查看所有未完全同步的分区
bin/kafka-topics.sh \
--bootstrap-server localhost:9092 \
--describe \
--under-replicated-partitions
答:
答:Follower 超过 replica.lag.time.max.ms(默认 30 秒)没有向 Leader 拉取消息,就会被踢出 ISR。这表示该 Follower 已经落后太多,不能保证数据一致性。
答:因为 ISR 中的副本数据与 Leader 基本一致,选它们做 Leader 不会丢失数据。如果从 OSR 中选举,选出的 Leader 可能缺少大量数据,导致数据不一致。
答:当 Producer 设置 acks=all 时,消息必须写入 ISR 中至少 min.insync.replicas 个副本才算成功。这个参数保证了最小的数据冗余度,防止在 ISR 数量不足时仍然写入成功导致数据风险。
答:当 ISR 为空时,是否允许从 OSR(不同步副本)中选举 Leader。如果允许(unclean.leader.election.enable=true),可能会选出数据落后的副本作为 Leader,导致数据丢失。这是用一致性换可用性。
AR = ISR ∪ OSR ISR ⊆ AR Leader ∈ ISR
ISR 是 Kafka 保证数据一致性的核心机制,它圈定了"可用且可靠"的副本集合,是 Leader 选举和数据确认的基准。
掌握了 ISR 和 AR 的概念,你就理解了 Kafka 高可用架构的精髓!

微信公众号「极客日志」,在微信中扫描左侧二维码关注。展示文案:极客日志 zeeklog
查找任何按下的键的javascript键代码、代码、位置和修饰符。 在线工具,Keycode 信息在线工具,online
JavaScript 字符串转义/反转义;Java 风格 \uXXXX(Native2Ascii)编码与解码。 在线工具,Escape 与 Native 编解码在线工具,online
使用 Prettier 在浏览器内格式化 JavaScript 或 HTML 片段。 在线工具,JavaScript / HTML 格式化在线工具,online
Terser 压缩、变量名混淆,或 javascript-obfuscator 高强度混淆(体积会增大)。 在线工具,JavaScript 压缩与混淆在线工具,online
将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online