欢迎跳转到本文的原文链接:https://honeypps.com/mq/kafka-basic-knowledge-of-lw-and-logstartoffset/
很多读者对 Kafka 中的 HW 的概念并不陌生,但是却并不知道还有一个 LW 的 概念。HW 是 High Watermark 的缩写,俗称高水位,它标识 了一个特定的消息偏移量(offset),消费者只能拉取到这个 offset 之前的消息。
如上图所示,它代表一个日志文件,这个日志文件中有 9 条消息,第一条消息的 offset( logStartOffset)为 0,最后一条消息的 offset 为 8,offset 为 9 的消息用虚线框表示,代表下一条待写入的消息。日志文件的 HW 为 6,表示消费者只能拉取到 offset 在 0 至 5 之间的消息, 而 offset 为 6 的消息对消费者而言是不可见的。
而LW 是 Low Watermark 的缩写,俗称“低水位”,代表 AR 集合中最小的 logStartOffset 值。副本的拉取请求(FetchRequest,它有可能触发新建日志分段而旧的被清理,进而导致 logStartOffset 的增加)和删除消息请求(DeleteRecordRequest)都有可能促使 LW 的增长。
在 Kafka 的日志管理器中会有一个专门的日志删除任务来周期性地检测和删除不符合保留条件的日志分段文件,这个周期可以通过 broker 端参数 log.retention.check.interval.ms来配置,默认值为 300000,即 5 分钟。当前日志分段的保留策略有 3 种:基于时间的保留策略、基于日志大小的保留策略和基于日志起始偏移量的保留策略。而“基于日志起始偏移量的保留策略”正是基于 logStartOffset来实现的。
一般情况下,日志文件的起始偏移量 logStartOffset 等于第一个日志分段的 baseOffset,但这并不是绝对的,logStartOffset 的值可以通过 DeleteRecordsRequest 请求(比如使用 KafkaAdminClient 的 deleteRecords()方法、使用 kafka-delete-records.sh 脚本、日志的清理和截断等操作进行修改。
基于日志起始偏移量的保留策略的判断依据是某日志分段的下一个日志分段的起始偏移量 baseOffset 是否小于等于 logStartOffset,若是,则可以删除此日志分段。如下图所示。
假设 logStartOffset 等于 25,日志分段 1 的起始偏移量为 0,日志分段 2 的起始偏移量为 11, 日志分段 3 的起始偏移量为 23,那么通过如下动作收集可删除的日志分段的文件集合 deletableSegments:
-
从头开始遍历每个日志分段,日志分段 1 的下一个日志分段的起始偏移量为11,小于logStartOffset 的大小,将日志分段1加入 deletableSegments。
-
日志分段 2 的下一个日志偏移量的起始偏移量为 23,也小于 logStartOffset 的大小, 将日志分段 2 页加入 deletableSegments。
-
日志分段 3 的下一个日志偏移量在 logStartOffset 的右侧,故从日志分段 3 开始的所有日志分段都不会加入 deletableSegments。
收集完可删除的日志分段的文件集合之后的删除操作同基于日志大小的保留策略和基于时间的保留策略相同,具体的可以参看之前的文章《Kafka 日志清理之Log Deletion》,这里不再赘述。
注意LogStartOffset不可以缩写为LSO,因为在Kafka中,LSO特指LogStableOffset,这个会在后面的《Kafka科普系列 | 什么是LSO?》中一一指出。
来源:本文摘录自《深入理解Kafka》一书中若干篇幅。
欢迎跳转到本文的原文链接:https://honeypps.com/mq/kafka-basic-knowledge-of-lw-and-logstartoffset/
欢迎支持笔者新作:《深入理解Kafka:核心设计与实践原理》和《RabbitMQ实战指南》,同时欢迎关注笔者的微信公众号:朱小厮的博客。