KAFKA LEO&HW基本概念
原文地址 https://www.cnblogs.com/youngchaolin/p/12641463.html
LEO&HW基本概念
- Base Offset:是起始位移,该副本中第一条消息的offset,如下图,这里的起始位移是0,如果一个日志文件写满1G后(默认1G后会log rolling),这个起始位移就不是0开始了。
- HW(high watermark):副本的高水印值,replica中leader副本和follower副本都会有这个值,通过它可以得知副本中已提交或已备份消息的范围,leader副本中的HW,决定了消费者能消费的最新消息能到哪个offset。如下图所示,HW值为8,代表offset为[0,8]的9条消息都可以被消费到,它们是对消费者可见的,而[9,12]这4条消息由于未提交,对消费者是不可见的。注意HW最多达到LEO值时,这时可见范围不会包含HW值对应的那条消息了,如下图如果HW也是13,则消费的消息范围就是[0,12]。
- LEO(log end offset):日志末端位移,代表日志文件中下一条待写入消息的offset,这个offset上实际是没有消息的。不管是leader副本还是follower副本,都有这个值。当leader副本收到生产者的一条消息,LEO通常会自增1,而follower副本需要从leader副本fetch到数据后,才会增加它的LEO,最后leader副本会比较自己的LEO以及满足条件的follower副本上的LEO,选取两者中较小值作为新的HW,来更新自己的HW值。
LEO&HW更新流程
LEO和HW的更新,需要区分leader副本和follower副本,两者上的更新情况不一样,整体参考下图简单示例。
LEO
包括leader副本和follower副本。
leader LEO:leader的LEO就保存在其所在的broker的缓存里,当leader副本log文件写入消息后,就会更新自己的LEO。
remote LEO和follower LEO:remote LEO是保存在leader副本上的follower副本的LEO,可以看出leader副本上保存所有副本的LEO,当然也包括自己的。follower LEO就是follower副本的LEO,因此follower相关的LEO需要考虑上面两种情况。
- case 1:如果是remote LEO,更新前leader需要确认follower的fetch请求包含的offset,这个offset就是follower副本的LEO,根据它对remote LEO进行更新。如果更新时尚未收到fetch请求,或者fetch请求在请求队列中排队,则不做更新。可以看出在leader副本给follower副本返回数据之前,remote LEO就先更新了。
- case 2:如果是follower LEO,它的更新是在follower副本得到leader副本发送的数据并随后写入到log文件,就会更新自己的LEO。
HW
包括leader副本和follower副本。
leader HW:它的更新是有条件的,参考书籍中给出了四种情况,如下是其中的一种,就是producer向leader副本写消息的情况,当满足四种情况之一,就会触发HW尝试更新。如下图所示更新时会比较所有满足条件的副本的LEO,包括自己的LEO和remote LEO,选取最小值作为更新后的leader HW。
四种情况如下,其中最常见的情况就是前两种。
1.producer向leader写消息,会尝试更新。
2.leader处理follower的fetch请求,先读取log数据,然后尝试更新HW。
3.副本成为leader副本时,会尝试更新HW。
4.broker崩溃可能会波及leader副本,也需要尝试更新。
follower HW:更新发生在follower副本更新LEO之后,一旦follower向log写完数据,它就会尝试更新HW值。比较自己的LEO值与fetch响应中leader副本的HW值,取最小者作为follower副本的HW值。可以看出,如果follower的LEO值超过了leader的HW值,那么follower HW值是不会超过leader HW值的。