【Kafka】图解 Leader 切换时发生数据不一致问题

543 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第12天,点击查看活动详情

在高水位 HW 机制下,Leader 切换时候会发生哪些问题?

会有两个主要问题:

  1. Leader 切换时发生数据丢失问题
  2. Leader 切换时发生数据不一致问题

为什么会有这两个问题?

因为 Leader 副本高水位更新和 Follower 副本高水位更新在时间上是存在错配的。

回顾下 LEOHW

LEO 作用:

  1. 负责推算 Leader partitionHW
  2. 更新 HW:当所有的 follower partitionLEO 推送给 Leader partition 时候,Leader partition 根据 min{LEO1...LEOn} 即可得到 LeaderHW

HW 作用:

  1. 更新 followerHW:当 follower 请求 leader 数据同步时候,leader 会返回自己的 HW, 然后 follower 会更新 min{Leader(HW),LEO}
  2. 划分已提交和未提交数据:HW=3,表示前3条数据是已经同步到其他所有的 follower 里面去了,所以也将其叫做 committed(已提交数据),消费者是消费不到 HW 之后的 uncommmitted 数据的
  3. 消费:Consumer 只能看到 base offsetHW offset 之间的数据,这部分数据是 committed,可以被消费。

图解 Leader 切换时发生数据不一致问题

问题重现流程主要是:

# 副本有 2 个,1 个 leader 和 1 个 follower
replication-factor = 2# 最小同步数为1,1个副本写入数据就认为写入成功
min.insync.replicas = 1
  1. LeaderFollower 同步数据
  2. Follower 宕机了,又重启了
  3. Leader宕机了,Follower 被选举成 Leader
  4. 同步数据

问题重现详细流程:

  1. 假设一开始:LeaderLEO = 2, HW = 1FollowerLEO = 1, HW = 1

2022-06-0810-02-40.png

  1. 请求拉取消息:Follower 发送 fetch 请求,Follower 写入数据,LeaderLEO = 2, HW = 1FollowerLEO = 1, HW = 1,还没同步完成

2022-06-0810-05-14.png

  1. 这时,Leader 宕机了后重启,Follower 被选举为 新Leader

2022-06-0810-07-59.png

  1. 这时,生产者发了一条新数据给 新LeaderLeaderLEO = 2, HW = 2FollowerLEO = 2, HW = 2,虽然两者 HW = 2,但数据不同。

2022-06-0810-14-51.png