0%

故障时保证数据一致性

Kafka 故障时的数据一致性保障:LEO 与 HW 的核心作用

Kafka 中,数据一致性指的是分区的多个副本(Leader 与 Follower)之间数据的同步状态 —— 故障恢复后,所有副本应保持相同的数据内容。这一目标主要通过 LEO(Log End Offset)HW(High Watermark) 两个核心指标,配合故障处理机制实现。

核心概念:LEO 与 HW

LEO(Log End Offset)

  • 定义:每个副本(Leader 或 Follower)本地日志中 “下一条待写入消息的偏移量”,即当前日志中最后一条消息的偏移量 + 1。
  • 举例:若副本日志中最后一条消息的偏移量是 5,则该副本的 LEO 为 6。
  • 作用:标记副本当前的 “数据写入进度”,Leader 和 Follower 各自维护自己的 LEO。

HW(High Watermark,高水位)

  • 定义:分区的 HW 是 ISR(同步副本集)中所有副本的 LEO 的最小值。
  • 举例:若分区的 ISR 包含 Leader(LEO=10)和 Follower1(LEO=8)、Follower2(LEO=9),则该分区的 HW 为 8(三者 LEO 的最小值)。
  • 核心意义:
    • HW 是 “消费者可见的最大偏移量”,消费者只能读取到 HW 之前的消息(即偏移量 ≤ HW-1 的消息)。
    • HW 之前的消息被认为是 “已提交的消息”(committed messages),确保所有 ISR 副本都已同步这些消息,即使发生故障也不会丢失。

故障处理:如何通过 LEO 和 HW 保证一致性

Follower 故障的恢复流程

Follower 故障后,需重新加入集群并与 Leader 同步数据,确保数据一致:

  • 步骤 1:Follower 故障时,Kafka 会将其临时踢出 ISR(因无法在 replica.lag.time.max.ms 内同步数据)。
  • 步骤 2:Follower 恢复后,首先读取本地磁盘记录的自身 HW,并截断日志中所有 offset ≥ HW 的消息(这些消息可能是故障前未同步完成的 “脏数据”)。
  • 步骤 3:从自身 HW 开始,向 Leader 重新同步数据(拉取 Leader 中从该 HW 开始的消息)。
  • 步骤 4:当 Follower 的 LEO 追上 Leader 的 LEO(或达到分区当前的 HW),证明其数据已与 Leader 一致,重新加入 ISR。

目的:通过截断未确认的消息并重新同步,确保 Follower 与 Leader 数据一致。

Leader 故障的恢复流程

Leader 故障后,需从 ISR 中选举新 Leader,并让其他副本与新 Leader 同步,保证数据一致:

  • 步骤 1:Leader 故障后,Kafka 从 ISR 中选举一个 Follower 作为新 Leader(通常选择 LEO 最大的 Follower,减少数据丢失风险)。
  • 步骤 2:新 Leader 确定后,其他 Follower(包括原 Leader 恢复后)会先读取分区当前的 HW(即故障前的 HW),并截断本地日志中所有 offset ≥ HW 的消息(这些消息可能未被原 ISR 全部同步)。
  • 步骤 3:所有 Follower 从新 Leader 同步数据,从 HW 开始拉取消息,直到各自的 LEO 与新 Leader 的 LEO 一致。

目的:以故障前的 HW 为基准,截断所有副本中未确认的消息,确保新 Leader 和 Follower 从同一基准线同步,避免数据不一致。

局限性:仅保证副本一致性,不直接解决丢失或重复

需要明确的是,LEO 和 HW 的机制仅保证副本之间的数据一致性(即所有副本的数据相同),但不能直接解决以下问题:

  • 数据丢失:若 Leader 故障时,某些消息仅写入 Leader 而未同步到 ISR 中的任何 Follower(即这些消息在 HW 之后),则会被截断,导致丢失。需配合 acks=-1min.insync.replicas ≥ 2 避免。
  • 数据重复:若 Leader 已同步消息到 ISR 但未返回 ACK 就故障,生产者会重试,可能导致新 Leader 重复写入。需通过幂等性或业务去重解决

欢迎关注我的其它发布渠道

表情 | 预览
快来做第一个评论的人吧~
Powered By Valine
v1.3.10