首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

Kafka之高水位线&日志结尾位置

【导读:数据是二十一世纪的石油,蕴含巨大价值,这是·情报通·大数据技术系列第[58]篇文章,欢迎阅读和收藏】

1 基本概念

Kafka 中 Topic 的每个 Partition 有一个预写式日志文件,每个 Partition 都由一系列有序的、不可变的消息组成,这些消息被连续的追加到 Partition 中, Partition 中的每个消息都有一个连续的序列号叫做 offset, 确定它在分区日志中唯一的位置。Kafka 每个 topic 的 partition 有 N 个副本 (replica) ,其中 N 是 topic 的复制因子。

水位或水印( watermark )一词,也可称为高水位 (high watermark) ,通常被用在流式处理领域,以表征元素或事件在基于时间层面上的进度。一个比较经典的表述为:流式系统保证在水位 t 时刻,创建时间( event time ) = t' 且 t' ≤ t 的所有事件都已经到达或被观测到。在 Kafka 中,水位的概念反而与时间无关,而是与位置信息相关。严格来说,它表示的就是位置信息,即位移( offset )。Kafka 源码中使用的名字是高水位 (high watermark) 。

日志结尾位置或日志末端位移 (log end offset) ,记录了该副本底层日志 (log) 中下一条消息的位移值。也就是说,如果 LEO=10 ,那么表示该副本保存了 10 条消息,位移值范围是 [0, 9] 。

2 术语解释

Kafka 分区下有可能有很多个副本 (replica) 用于实现冗余,从而进一步实现高可用。副本根据角色的不同可分为 3 类:

leader 副本:响应 clients 端读写请求的副本

follower 副本:被动地备份 leader 副本中的数据,不能响应 clients 端读写请求。

ISR 副本:包含了 leader 副本和所有与 leader 副本保持同步的 follower 副本

每个 Kafka 副本对象都有两个重要的属性:LEO 和 HW 。

LEO :即日志末端位移 (log end offset) ,记录了该副本底层日志 (log) 中下一条消息的位移值。

HW :即上面提到的水位值。对于同一个副本对象而言,其 HW 值不会大于 LEO 值。小于等于 HW 值的所有消息都被认为是“已备份”的( replicated )。同理, leader 副本和 follower 副本的 HW 更新是有区别的。

3 详细说明

形象化地说明两者的关系:

上图中, HW 值是 7 ,表示位移是 0~7 的所有消息都已经处于“已备份状态”( committed ),而 LEO 值是 15 ,那么 8~14 的消息就是尚未完全备份( fully replicated )——为什么没有 15 ?因为刚才说过了, LEO 指向的是下一条消息到来时的位移,故上图使用虚线框表示。我们总说 consumer 无法消费未提交消息。这句话如果用以上名词来解读的话,应该表述为:consumer 无法消费分区下 leader 副本中位移值大于分区 HW 的任何消息。这里需要特别注意分区 HW 就是 leader 副本的 HW 值。

既然副本分为 leader 副本和 follower 副本,而每个副本又都有 HW 和 LEO ,那么它们是怎么被更新的呢?它们更新的机制又有什么区别呢?

3.1 follower副本何时更新LEO

如前所述, follower 副本只是被动地向 leader 副本请求数据,具体表现为 follower 副本不停地向 leader 副本所在的 broker 发送 FETCH 请求,一旦获取消息后写入自己的日志中进行备份。那么 follower 副本的 LEO 是何时更新的呢?Kafka 有两套 follower 副本 LEO :1. 一套 LEO 保存在 follower 副本所在 broker 的副本管理机中;2. 一套 LEO 保存在 leader 副本所在 broker 的副本管理机中,也就是说, eader 副本机器上保存了所有的 follower 副本的 LEO 。

为什么要保存两套?这是因为 Kafka 使用前者帮助 follower 副本更新其 HW 值;而利用后者帮助 leader 副本更新其 HW 使用。

3.1.1 follower 副本端的 follower 副本 LEO 何时更新

follower 副本端的 LEO 值就是其底层日志的 LEO 值,也就是说每当新写入一条消息,其 LEO 值就会被更新 ( 类似于 LEO += 1) 。当 follower 发送 FETCH 请求后, leader 将数据返回给 follower ,此时 follower 开始向底层 log 写数据,从而自动地更新 LEO 值

3.1.2 leader 副本端的 follower 副本 LEO 何时更新

leader 副本端的 follower 副本 LEO 的更新发生在 leader 在处理 follower FETCH 请求时。一旦 leader 接收到 follower 发送的 FETCH 请求,它首先会从自己的 log 中读取相应的数据,但是在给 follower 返回数据之前它先去更新 follower 的 LEO 。

3.2 follower 副本何时更新 HW

follower 更新 HW 发生在其更新 LEO 之后,一旦 follower 向 log 写完数据,它会尝试更新它自己的 HW 值。具体算法就是比较当前 LEO 值与 FETCH 响应中 leader 的 HW 值,取两者的小者作为新的 HW 值,因此,如果 follower 的 LEO 值超过了 leader 的 HW 值,那么 follower HW 值是不会越过 leader HW 值的。

3.3 leader 副本何时更新 LEO

和 follower 更新 LEO 道理相同, leader 写 log 时就会自动地更新它自己的 LEO 值。

3.4 leader 副本何时更新 HW 值

它直接影响了分区数据对于 consumer 的可见性 ,以下 4 种情况下 leader 会尝试去更新分区 HW ——切记是尝试,有可能因为不满足条件而不做任何更新:

· 副本成为 leader 副本时:当某个副本成为了分区的 leader 副本, Kafka 会尝试去更新分区 HW 。

· broker 出现崩溃导致副本被踢出 ISR 时:若有 broker 崩溃则必须查看下是否会波及此分区,因此检查下分区 HW 值是否需要更新是有必要的。

· producer 向 leader 副本写入消息时:因为写入消息会更新 leader 的 LEO ,故有必要再查看下 HW 值是否也需要修改

· leader 处理 follower FETCH 请求时:当 leader 处理 follower 的 FETCH 请求时首先会从底层的 log 读取数据,之后会尝试更新分区 HW 值

最后两个。它揭示了一个事实——当 Kafka broker 都正常工作时,分区 HW 值的更新时机有两个:leader 处理 PRODUCE 请求时和 leader 处理 FETCH 请求时。

leader 是如何更新它的 HW 值的呢?leader broker 上保存了一套 follower 副本的 LEO 以及它自己的 LEO 。当尝试确定分区 HW 时,它会选出所有满足条件的副本,比较它们的 LEO( 当然也包括 leader 自己的 LEO) ,并选择最小的 LEO 值作为 HW 值。这里的满足条件主要是指副本要满足以下两个条件之一:

· 处于 ISR 中

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20200212A0T9MV00?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券