定义
- kafka 中的高水位(High Watermark, HW)是和位置信息绑定的
- offset 相关
- Log End Offset,简写是 LEO。它表示副本写入下一条消息的位移值
- 同一个副本对象,其 HW 不会大于 LEO 值
- 即 [HW,LEO) 为未提交消息
- 分区的 HW 就是其 Leader 副本的 HW
作用
- 定义消息可见性,即用来标识分区下的哪些消息是可以被消费者消费的
- 帮助 Kafka 完成副本同步
更新机制
- 每个副本对象都保存了一组 HW 值和 LEO 值
- Leader 副本所在的 Broker 上,还保存了相同分区剩余 Follower 副本(又称远程副本)的 LEO 值(但是不保存 HW)
Leader 副本
处理生产者请求
- 写入消息到本地磁盘
- 更新 LEO 值
- 更新分区高水位值
i. 获取 Leader 副本所在 Broker 端保存的所有远程副本 LEO 值{LEO-1,LEO-2,……,LEO-n}
ii. 获取 Leader 副本高水位值:currentHW。
iii. 更新 currentHW = min(currentHW, LEO-1,LEO-2,……,LEO-n)
处理 Follower 副本拉取消息
- 读取磁盘(或页缓存)中的消息数据
- 使用 Follower 副本发送请求中的位移值更新远程副本 LEO 值
- 更新分区高水位值(具体步骤与处理生产者请求的步骤相同)
- 将 HW 发送给 Follower 副本
Follower 副本
从 Leader 拉取消息
- 写入消息到本地磁盘
- 更新 LEO 值
- 更新高水位值
i. 获取 Leader 发送的高水位值响应:currentHW
ii. 获取步骤 2 中更新过的 LEO 值:currentLEO
iii. 更新 currentHW= min(currentHW, currentLEO)
- 注意,最新的 HW 需要在下次 Leader 获取
流程
Leader Epoch
- Leader 副本 HW 更新和 Follower 副本HW 更新在时间上是存在错配的
- 社区在 0.11 版本正式引入了 Leader Epoch 概念
组成
- Epoch。一个单调增加的版本号
- 每当副本领导权发生变更时,都会增加该版本号
- 小版本号的 Leader 被认为是过期 Leader,不能再行使 Leader 权力
- 起始位移(Start Offset)
- Leader 副本在该 Epoch 值上写入的首条消息的位移
实现
- Kafka Broker 会在内存中为每个分区都缓存 Leader Epoch 数据,同时它还会定期地将这些信息持久化到一个 checkpoint 文件中
- Leader 副本写入消息到磁盘时,Broker 会尝试更新这部分缓存。
- 如果该 Leader 是首次写入消息,那么 Broker 会向缓存中增加一个 Leader Epoch 条目,否则就不做更新。