Appearance
Kafka数据可靠性保证
kafka副本核心概念
首先来介绍下Kafka副本角色与分工,Kafka 的每个分区(Partition)有多个副本(Replica),分为以下角色:
副本类型 | 作用 | 读写权限 |
---|---|---|
Leader | 处理所有读写请求,负责与生产者/消费者交互 | 读 + 写 |
Follower | 从 Leader 拉取数据保持同步,不处理客户端请求 | 只读 |
Observer | 与 Follower 类似,但不参与 Leader 选举(Kafka 2.4+ 引入,用于跨地域同步) | 只读 |
AR与ISR
- AR(Assigned Replicas):分区的所有副本集合,包括 Leader 和 Follower。
- ISR(In-Sync Replicas):当前与 Leader 保持数据同步的副本集合(包含 Leader 本身)。
- 动态管理:Follower 若在
replica.lag.time.max.ms
(默认 30s)内未完成同步,会被移出 ISR;同步恢复后自动重新加入。 - Leader 选举:仅 ISR 中的副本有资格成为新 Leader。
acks=all
:需等待 ISR 中所有副本确认,而非所有 AR 副本。
- 动态管理:Follower 若在
- OSR(Out-of-Sync Replicas):未与 Leader 保持同步的副本集合。
- OSR 副本无法参与 Leader 选举。
- 常见场景:Broker 宕机或网络延迟过大时,副本会被划入 OSR。
副本同步
副本同步原理
- LEO:每个副本的"书签",记录当前写到哪里了;
- Leader的LEO = 最新内容的位置
- Follower的LEO = 当前抄写到的位置
- HW:高水印值,一定不会大于LEO值,小于 HW 值的消息被认为是“已提交”或“已备份”的消息,对消费者可见。
- 消费者:只能读到HW之前的内容
- 生产者:HW之后的数据可能被截断(如Leader切换时)
- Remote LEO:远程LEO,Leader记录的每个Follower的LEO。
- 作用:Leader通过这些信息计算HW
最小同步副本数
定义:必须至少同步到N个节点才算成功。
properties
min.insync.replicas=2 // 至少需要Leader+1个Follower确认
acks=all // 必须等待这2个站点都签收
java
Properties props = new Properties();
props.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, "localhost:9092");
props.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class.getName());
props.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, StringSerializer.class.getName());
// 设置可靠性参数
props.put(ProducerConfig.ACKS_CONFIG, "all"); // 等待所有同步副本确认
props.put("min.insync.replicas", 2); // 至少2个副本确认
假设我们一共配置了3个分区:
配置 | 可靠性 | 风险场景 |
---|---|---|
min=1 | 低 | Leader宕机可能丢数据 |
min=2 | 中 | 允许1个副本掉队 |
min=3 | 高 | 任何副本宕机都会导致消息无法被消费 |
常见问题
Q1:为什么消费者看不到最新数据?
- 答案:因为HW还没更新(最慢的快递员还没上报进度)
Q2:Leader挂了如何恢复?
- 从ISR中选新Leader。
- 新Leader对比所有Follower,以HW为基准删除不一致数据(所以此时可能丢数据,因为远程在同步中,但是主节点挂了,导致新选上来的Leader的HW数据低于真实的HW。)
- 要求其他Follower按新Leader的数据重新同步。
Q3:如何避免Follower掉队?
优化网络(减少快递运输时间)
监控
UnderReplicatedPartitions
指标设置合理参数:
propertiesreplica.lag.time.max.ms=60000 // 允许1分钟延迟 min.insync.replicas=2 // 3副本时允许1个故障
警告
最小同步副本数只有ACKS=ALL的时候才生效!