Kafka 偏移量与高水位
Kafka 分区内消息偏移量(Offset)、高水位(HW)、末端偏移(LEO)原理与消息可见性。
下面把 偏移量 Offset、水位 LEO/HW、消息可见性 拆到能懂、能背、能面试的程度,全程结合原理、公式、例子和常见误区。
一、偏移量 Offset(分区内消息的唯一编号)
1. 基本定义
- Offset:分区内每条消息的顺序编号,从 0 开始递增,分区内唯一。
- 一条消息 =
(offset, key, value, timestamp)。 - 分区是 Kafka 读写的最小单位;不同分区 offset 独立,互不干扰。
2. 常见 Offset 类型
- LogStartOffset(LSO,分区起始偏移)
- 分区日志最老有效消息的 offset。
- 随日志清理(删除/压缩)单调递增。
- 消费者不能消费
< LogStartOffset的消息(已删除)。
- ConsumerOffset(消费偏移)
- 某个消费者组在某个分区消费到的位置。
- 存在 Kafka 内部
__consumer_offsets主题。 - 每次提交位移,就是把
ConsumerOffset存下来,下次从这里继续。
- LEO(Log End Offset,日志末端偏移)
- 每个副本(Leader/Follower)自己的:最后一条消息 offset + 1。
- 公式:
LEO = 最新写入位置 - Leader 的 LEO:由生产者写入速度决定;
- Follower 的 LEO:由同步 Leader 的速度决定。
例子:
消息0 消息1 消息2
↑ ↑
offset=0 LEO=3
3. Offset 的作用
- 定位消息:消费者按 offset 精准拉取;
- 顺序保证:分区内消息严格有序;
- 消费断点:
ConsumerOffset决定“下次从哪读”。
二、水位:HW(High Watermark,高水位)——可见性分界线
1. 定义与公式
- HW(高水位):分区 ISR 集合中所有副本 LEO 的最小值。
- 公式:
HW = min(ISR 里所有副本的 LEO)
- 含义:所有 ISR 副本都已同步到的最高 offset。
2. 可见性铁律(最关键)
消费者只能看到 offset < HW 的消息;offset ≥ HW 对消费者不可见。
offset < HW:已提交(committed),安全可消费;offset ≥ HW:未提交(uncommitted),对消费者隐藏,即使 Leader 已经写入。
3. 举个直观例子(3 副本,ISR=全部)
- Leader:LEO=8
- Follower1:LEO=7
- Follower2:LEO=6
则:
- HW = min(8,7,6) = 6
- 消费者最多读到 offset=5;
- offset=6,7,8:Leader 有,但 Follower2 没有 → 不可见。
4. HW 的核心作用
- 保证消费安全:消费者永远看不到“只在部分副本存在”的消息,避免 Leader 宕机后消息消失但消费者已处理的 inconsistency;
- 决定消息可见性:是 Kafka “已提交”的定义线;
- 副本同步基准:Follower 同步必须追到 HW,才算是真正“追上”。
三、LEO vs HW 对比(必背)
| 概念 | 全称 | 含义 | 可见性 | 更新时机 |
| LEO | Log End Offset | 副本自己的日志末尾(下一条写入 offset) | 内部记录,不直接决定可见性 | 副本写入消息即更新 |
| HW | High Watermark | ISR 中最小 LEO,全局已提交边界 | 消费者只能看 < HW | Follower 同步后,Leader 重新计算 |
一句话:LEO 是“写到哪”,HW 是“安全到哪、能看到哪”。
四、消息可见性完整流程(从生产到消费)
1. 生产者写入
- 生产者发消息 → Leader 追加到本地日志 → Leader LEO+1。
- 此时 Follower 还没拉取 → Follower LEO 不变 → HW 不变。
- 新消息 ≥ HW → 消费者看不到。
2. Follower 同步
- Follower 拉取 Leader 数据 → 写入本地日志 → Follower LEO+1。
- 当所有 ISR Follower 都追到新 LEO → Leader 重新计算 HW → HW 推进。
3. 消费者拉取
- 消费者发 Fetch → Leader 返回 offset ∈ [ConsumerOffset, HW-1] 的消息。
- HW 不前进,消费者就不能读新数据——即使 Leader 已经写了很多。
4. 异常场景:Leader 宕机
- 新 Leader 从 ISR 中选;
- 新 Leader 的 LEO ≥ 原 HW;
- 原 HW 以下消息全部安全保留;
- 原 HW 以上、新 Leader 没有的消息 → 直接丢弃(本来也没对消费者可见)。
五、ISR 与 HW 的关系(面试高频)
- ISR(In-Sync Replicas):与 Leader 保持同步的副本集合(含 Leader)。
- HW 只看 ISR 内副本;不在 ISR 的落后副本,不参与 HW 计算。
- 落后 Follower 被踢出 ISR → ISR 缩小 → HW 可能瞬间推进(因为 min 不用算它了)。
例子:
- 原 ISR:Leader(8), F1(7), F2(5) → HW=5
- F2 落后太久被踢 → ISR:Leader(8), F1(7) → HW=7
- 消费者立刻能读到 offset=5、6。
六、事务场景:LSO(Log Stable Offset)
普通消息:可见性由 HW 决定;事务消息:可见性由 LSO 决定(LSO ≤ HW)。
- LSO:事务状态稳定的 offset;
- 未提交事务的消息,即使 < HW,事务消费者也看不到;
- 事务提交后,LSO 推进,消息才可见。
七、一句话总结(背下来)
- Offset:分区内消息唯一序号;
- LEO:副本自己写到哪;
- HW:ISR 全副本都追到的安全线,消费者只能看 HW 之前;
- 可见性:生产者写 → Leader LEO 涨 → Follower 追 → HW 涨 → 消费者才能读。
要不要我把以上内容浓缩成一页面试速记(含关键公式+易错点对比),方便你直接背诵?
关联文档
- Kafka 底层原理详解 — 分区与副本
- HW、LEO、LeaderEpoch 完整原理 — 高水位与 Leader Epoch
- Kafka 高可用架构完整详解 — 高可用机制