欢迎跳转到本文的原文链接:https://honeypps.com/mq/kafka-basic-knowledge-of-lso/
很多同学对于Kafka的认知仅限于在LEO和HW之间,有可能认知还出现错误,对此记住一点,这两个都是指最后一条的下一条的位置而不是指最后一条的位置。不过本文的关注点不在于此,而在于LSO这个概念。如果需要了解LEO和HW的同学可在文末留言,后面也可以考虑出个科普LEO和HW的文章。
LSO特指LastStableOffset,在上一篇《Kafka科普系列 | 什么是LW和logStartOffset》中提及过这个概念,它具体的与Kafka的事务有关。
可能大家在使用Kafka的时候并没有太在意一个消费端的参数——isolation.level,这个参数用来配置消费者的事务隔离级别。字符串类型,有效值为“read_uncommitted”和 “read_committed”,表示消费者所消费到的位置,如果设置为“read_committed”,那么消费者就会忽略事务未提交的消息,即只能消费到 LSO(LastStableOffset)的位置,默认情况下为 “read_uncommitted”,即可以消费到 HW(High Watermark)处的位置。注意:follower副本的事务隔离级别也为“read_uncommitted”,并且不可修改。
对于Kafka中事务的讲解会在后面的系列文章《Kafka科普系列 | 什么是Kafka的事务?》中进行解答,在这里只需了解:在开启Kafka事务时,生产者发送了若干消息(比如msg1、msg2、msg3)到broker中,如果生产者没有提交事务(执行commitTransaction),那么对于isolation.level = read_committed的消费者而言是看不到这些消息的,而isolation.level = read_uncommitted则可以看到。事务中的第一条消息的位置可以标记为firstUnstableOffset(也就是msg1的位置)。
这个LSO还会影响Kafka消费滞后量(也就是Kafka Lag,很多时候也会被称之为消息堆积量)的计算。不妨我们先来看一下下面这幅图。
在图中,对每一个分区而言,它的 Lag 等于 HW – ConsumerOffset 的值,其中 ConsumerOffset 表示当前的消费位移。当然这只是针对普通的情况。如果为消息引入了事务,那么 Lag 的计算方式就会有所不同。
如果消费者客户端的 isolation.level 参数配置为“read_uncommitted”(默认),那么 Lag的计算方式不受影响;如果这个参数配置为“read_committed”,那么就要引入 LSO 来进行计 算了。
对未完成的事务而言,LSO 的值等于事务中第一条消息的位置(firstUnstableOffset,如上图所示),对已完成的事务而言,它的值同 HW 相同, 所以我们可以得出一个结论:LSO≤HW≤LEO。(如下图所示)
所以,对于分区中有未完成的事务,并且消费者客户端的 isolation.level 参数配置为“read_committed”的情况,它对应的 Lag 等于 LSO – ConsumerOffset 的值。
这个知识点的掌握也能够为你在面试环节中加分。大多数情况下,除非面试官是专门做Kafka相关的开发工作,一般很少有人会关注LSO这个东西,也就是说大概率情况下面试官也不知道这是什么。“什么是Kafka Lag,怎么计算Kafka Lag”类似这种问题反而会被经常问及,那么你在回答完HW - ConsumedOffset=Lag之后,如果再接着补上LSO的内容,相信面试官会为之眼前一亮。
来源:本文修改自《深入理解Kafka》一书中若干篇幅。
欢迎跳转到本文的原文链接:https://honeypps.com/mq/kafka-basic-knowledge-of-lso/
欢迎支持笔者新作:《深入理解Kafka:核心设计与实践原理》和《RabbitMQ实战指南》,同时欢迎关注笔者的微信公众号:朱小厮的博客。