基于本文回答
0
评论

什么是Kafka 的ISR,ISR 列表又是如何动态更新的?

知识点图片

在 Kafka 中,ISR 和它的动态更新机制是 Kafka 实现高可用性(High Availability)数据一致性的核心设计。

以下是关于 ISR 及其动态更新机制的详细解析:


一、 什么是 Kafka 的 ISR?

ISR 的全称是 In-Sync Replicas(同步副本集合)

在 Kafka 中,每个主题的分区(Partition)可以配置多个副本(Replica)以防数据丢失。这些副本分为一个 Leader 和多个 Follower。

  • AR (All Replicas):所有的副本统称为 AR。
  • ISR (In-Sync Replicas):与 Leader 保持“同步”的副本集合。Leader 副本自己始终在 ISR 中
  • OSR (Out-of-Sync Replicas):与 Leader 失去“同步”的副本集合。

公式:AR = ISR + OSR

为什么需要 ISR?(设计目的)

传统的分布式系统要么采用同步复制(等待所有副本写完才返回成功,性能极差),要么采用异步复制(Leader 写完就返回,Follower 慢慢拉取,容易丢数据)。
Kafka 的 ISR 是一种折中方案
当生产者设置 acks=all(或 acks=-1)时,Leader 只需要等待 ISR 列表中的所有副本都确认写入成功,就会向生产者返回成功,而不需要等待 OSR 中的慢节点。这既保证了只要 ISR 中有一个副本存活数据就不会丢失,又避免了被个别宕机或网络慢的副本拖垮整体性能。


二、 ISR 列表是如何动态更新的?

ISR 并不是静态不变的,它会根据 Follower 副本的健康状况和同步速度动态收缩(移除副本)扩张(加入副本)

1. 评判“是否同步”的标准(核心参数)

在 Kafka 0.9.0.0 版本之后,判断一个 Follower 是否能留在 ISR 中的唯一标准是时间参数:
replica.lag.time.max.ms(默认值为 30000ms,即 30 秒)。

只要满足以下任意一种情况,Follower 就会被认为“失去同步”,从而被踢出 ISR:

  • 网络断开/宕机:Follower 在 30 秒内没有向 Leader 发送任何 Fetch(拉取)请求。
  • 同步太慢:Follower 虽然在拉取数据,但它落后 Leader 的时间超过了 30 秒(即它在 30 秒内都没能追赶上 Leader 的最新数据位置)。

(注:在旧版本中还有一个参数 replica.lag.max.messages 根据落后消息数量来判断,但由于流量突发时容易造成 Follower 频繁进出 ISR(引发性能抖动),该参数已被废弃。)

2. ISR 收缩(剔除掉队副本的过程)

当 Follower 发生故障或网络延迟变高时,踢出流程如下:

  1. Leader 监控:Leader 副本内部会维护一个跟踪 Follower 状态的定时任务。
  2. 判定超时:如果 Leader 发现某个 Follower 超过 replica.lag.time.max.ms 没有发送拉取请求,或者没有追上 Leader 的最新偏移量(LEO)。
  3. 发起移除:Leader 会将该 Follower 从内存中的本地 ISR 列表中移除。
  4. 元数据更新:Leader 向 Kafka 集群的 Controller(控制器) 发送 AlterISR 请求。
  5. 持久化:Controller 收到请求后,更新元数据(ZooKeeper 或 KRaft 模式下的元数据日志),将该 Follower 正式放入 OSR 列表。

3. ISR 扩张(恢复的副本重新加入的过程)

当宕机的 Follower 重启,或者网络恢复后,它需要重新加入 ISR,流程如下:

  1. 持续拉取:Follower 恢复后,开始疯狂向 Leader 发送 Fetch 请求,拉取落后的数据。
  2. 追平数据:当 Follower 的 Log End Offset(LEO,日志末端位移)追赶上了 Leader 当前的 High Watermark(HW,高水位)或 LEO。换句话说,Follower 把落后的数据全部补齐了。
  3. 发起加入:Leader 发现该 Follower 已经完全跟上自己的进度,就将其重新加入本地内存的 ISR 列表中。
  4. 元数据更新:Leader 再次向 Controller 发送 AlterISR 请求。
  5. 持久化:Controller 更新集群元数据,该 Follower 正式回归 ISR,参与后续的 acks=all 的写入确认。

三、 总结与延伸

  • ISR 的本质:它是 Kafka 为平衡数据可靠性吞吐量而发明的一种动态机制。
  • 极端情况(min.insync.replicas):如果网络极其恶劣,所有 Follower 都被踢出了 ISR,ISR 中只剩下 Leader 自己。此时如果 acks=all,依然算写入成功。但为了防止 Leader 单点故障导致数据丢失,Kafka 提供了 min.insync.replicas 参数(默认是 1,生产环境建议设为 2)。如果当前 ISR 里的副本数量小于这个值,Kafka 会拒绝写入(抛出 NotEnoughReplicasException),优先保证数据绝对不丢,牺牲部分可用性。
右滑查看面试常问