Kafka

Kafka 偏移量与高水位

·7 分钟阅读·2776 字

Offset、HW(高水位)、LEO——Kafka 消息偏移量、水位线与消息可见性原理

📋 目录

Kafka 偏移量与高水位

Kafka 分区内消息偏移量(Offset)、高水位(HW)、末端偏移(LEO)原理与消息可见性。


下面把 偏移量 Offset、水位 LEO/HW、消息可见性 拆到能懂、能背、能面试的程度,全程结合原理、公式、例子和常见误区。


一、偏移量 Offset(分区内消息的唯一编号)

1. 基本定义

  • Offset:分区内每条消息的顺序编号,从 0 开始递增,分区内唯一。
  • 一条消息 = (offset, key, value, timestamp)
  • 分区是 Kafka 读写的最小单位;不同分区 offset 独立,互不干扰。

2. 常见 Offset 类型

  1. LogStartOffset(LSO,分区起始偏移)
  • 分区日志最老有效消息的 offset。
  • 随日志清理(删除/压缩)单调递增
  • 消费者不能消费 < LogStartOffset 的消息(已删除)。
  1. ConsumerOffset(消费偏移)
  • 某个消费者组在某个分区消费到的位置
  • 存在 Kafka 内部 __consumer_offsets 主题。
  • 每次提交位移,就是把 ConsumerOffset 存下来,下次从这里继续。
  1. 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 的核心作用

  1. 保证消费安全:消费者永远看不到“只在部分副本存在”的消息,避免 Leader 宕机后消息消失但消费者已处理的 inconsistency;
  2. 决定消息可见性:是 Kafka “已提交”的定义线;
  3. 副本同步基准:Follower 同步必须追到 HW,才算是真正“追上”。

三、LEO vs HW 对比(必背)

概念全称含义可见性更新时机
LEOLog End Offset副本自己的日志末尾(下一条写入 offset)内部记录,不直接决定可见性副本写入消息即更新
HWHigh WatermarkISR 中最小 LEO,全局已提交边界消费者只能看 < HWFollower 同步后,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 涨 → 消费者才能读。

要不要我把以上内容浓缩成一页面试速记(含关键公式+易错点对比),方便你直接背诵?


关联文档