在 kafka中,什么是 HW(High Watermark)和 LEO(Log End Offset)?
在 Apache Kafka 中,HW (High Watermark) 和 LEO (Log End Offset) 是两个非常核心的概念,它们主要用于副本机制(Replication)、数据一致性以及消费者可见性的控制。
简单来说,LEO 代表日志的末端,而 HW 代表消费者能读到的安全水位线。
以下是详细的解释:
1. LEO (Log End Offset)
定义:
LEO 是 Log End Offset 的缩写,表示下一条消息将要被写入日志的位移(Offset)。
关键点:
- 它是“下一个”位置:如果当前日志中最后一条消息的 Offset 是 9,那么 LEO 就是 10。
- 每个副本都有自己的 LEO:Leader 副本和 Follower 副本各自维护自己的 LEO。
- 增长方式:
- Leader:当生产者发送消息,Leader 写入本地日志后,Leader 的 LEO 增加。
- Follower:当 Follower 向 Leader 发起 Fetch 请求同步数据并写入本地日志后,Follower 的 LEO 增加。
公式理解:
2. HW (High Watermark)
定义:
HW 是 High Watermark(高水位)的缩写。它标记了一个特定的 Offset,消费者只能拉取到 HW 之前的消息。
关键点:
- 消费者可见性:HW 定义了消息的“已提交(Committed)”状态。只有被 ISR(In-Sync Replicas,同步副本集合)中所有副本都保存了的消息,才会被认为是“已提交”的,HW 就是指向这个位置。
- 取值逻辑:HW 的值等于 ISR 集合中最小的那个 LEO。这体现了“木桶效应”,即数据的安全性取决于同步最慢的那个副本。
- 数据截断:当副本发生故障重启,ec或者进行 Leader 切换时,HW 会作为数据截断的依据,确保副本间的数据一致性。
关系: (HW 永远不会超过 LEO)
3. 图解 HW 与 LEO 的关系
假设有一个分区,有 1 个 Leader 和 2 个 Follower,且都在 ISR 列表中。
场景: Leader 写入了两条新消息(Offset 4 和 5),Follower 1 同步了 Offset 4,Follower 2 还没来得及同步。
plaintext
Offset: [0] [1] [2] [3] [4] [5]
-----------------------
Leader Log: [x] [x] [x] [x] [x] [x] -> LEO = 6
Follower 1: [x] [x] [x] [x] [x] -> LEO = 5
Follower 2: [x] [x] [x] [x] -> LEO = 4
ISR 集合 LEOs: {6, 5, 4}
HW = min(6, 5, 4) = 4
此时的状态:
- Leader LEO: 6
- HW: 4
- 消费者可见范围: 只能读到 Offset 0, 1, 2, 3。虽然 Leader 上有 4 和 5,但因为 HW 是 4,所以 4 和 5 对消费者不可见。
- 原因: 如果此时 Leader 宕机,Follower 2 可能被选为新 Leader。如果消费者读到了 Offset 5,但新 Leader (Follower 2) 只有到 Offset 3 的数据,就会发生数据丢失/不一致。HW 机制就是为了防止这种情况。
4. HW 和 LEO 的更新流程
理解它们是如何变化的,有助于理解 Kafka 的高可用机制:
- Producer 发送消息:消息写入 Leader 本地 Log,Leader 的 LEO 增加。
- Follower 拉取消息:Follower 向 Leader 发送 FETCH 请求(携带自己的 LEO)。
- Leader 处理 FETCH:
- 读取数据返回给 Follower。
- Leader 根据 Follower 请求中的 LEO,更新 Leader 端维护的该 Follower 的 LEO 信息。
- Leader 重新计算 HW(取 ISR 中最小 LEO),如果 HW 增长,更新 Leader 的 HW。
- Follower 接收响应:
- 将消息写入本地 Log,更新自己的 LEO。
- 更新自己的 HW(取 Leader 返回的 HW 和自己 LEO 的较小值)。
5. 总结与对比
| 特性 | LEO (Log End Offset) | HW (High Watermark) |
|---|---|---|
| 含义 | 日志末端位移(下一条写入位置) | 高水位(已提交消息的边界) |
| 物理意义 | 代表数据存储的物理进度 | 代表数据一致性的逻辑进度 |
| 消费者可见性 | 消费者不可见 LEO(除非 HW=LEO) | 消费者只能消费到 HW 之前的消息 |
| 主要作用 | 标识日志写入长度 | 1. 控制消费者读取范围 2. 副本间数据截断/恢复的基础 |
| 大小关系 | 总是 HW | 总是 LEO |
一句话总结:
LEO 是副本自己默默记账写到了哪里,HW 是 Leader 告诉大家哪些数据已经安全同步了,可以放心给消费者看了。
右滑查看面试常问