Kafka日志清理之Log Deletion
歡迎支持筆者新作:《深入理解Kafka:核心設計與實踐原理》和《RabbitMQ實戰指南》,同時歡迎關注筆者的微信公眾號:朱小廝的博客。
歡迎跳轉到本文的原文鏈接:https://honeypps.com/mq/log-deletion-of-kafka-log-retention/
Kafka將消息存儲在磁盤中,為了控制磁盤占用空間的不斷增加就需要對消息做一定的清理操作。Kafka中每一個分區partition都對應一個日志文件,而日志文件又可以分為多個日志分段文件,這樣也便于日志的清理操作。Kafka提供了兩種日志清理策略:
我們可以通過broker端參數log.cleanup.policy來設置日志清理策略,此參數默認值為“delete”,即采用日志刪除的清理策略。如果要采用日志壓縮的清理策略的話,就需要將log.cleanup.policy設置為“compact”,并且還需要將log.cleaner.enable(默認值為true)設定為true。通過將log.cleanup.policy參數設置為“delete,compact”還可以同時支持日志刪除和日志壓縮兩種策略。日志清理的粒度可以控制到topic級別,比如與log.cleanup.policy對應的主題級別的參數為cleanup.policy,為了簡化說明,本文只采用broker端參數做陳述,如若需要topic級別的參數可以查看官方文檔。
日志刪除
Kafka日志管理器中會有一個專門的日志刪除任務來周期性檢測和刪除不符合保留條件的日志分段文件,這個周期可以通過broker端參數log.retention.check.interval.ms來配置,默認值為300,000,即5分鐘。當前日志分段的保留策略有3種:基于時間的保留策略、基于日志大小的保留策略以及基于日志起始偏移量的保留策略。
1. 基于時間
日志刪除任務會檢查當前日志文件中是否有保留時間超過設定的閾值retentionMs來尋找可刪除的的日志分段文件集合deletableSegments,參考下圖所示。retentionMs可以通過broker端參數log.retention.hours、log.retention.minutes以及log.retention.ms來配置,其中log.retention.ms的優先級最高,log.retention.minutes次之,log.retention.hours最低。默認情況下只配置了log.retention.hours參數,其值為168,故默認情況下日志分段文件的保留時間為7天。
查找過期的日志分段文件,并不是簡單地根據日志分段的最近修改時間lastModifiedTime來計算,而是根據日志分段中最大的時間戳largestTimeStamp來計算。因為日志分段的lastModifiedTime可以被有意或者無意的修改,比如執行了touch操作,或者分區副本進行了重新分配,lastModifiedTime并不能真實地反映出日志分段在磁盤的保留時間。要獲取日志分段中的最大時間戳largestTimeStamp的值,首先要查詢該日志分段所對應的時間戳索引文件,查找時間戳索引文件中最后一條索引項,若最后一條索引項的時間戳字段值大于0,則取其值,否則才設置為最近修改時間lastModifiedTime。
若待刪除的日志分段的總數等于該日志文件中所有的日志分段的數量,那么說明所有的日志分段都已過期,但是該日志文件中還要有一個日志分段來用于接收消息的寫入,即必須要保證有一個活躍的日志分段activeSegment,在此種情況下,會先切分出一個新的日志分段作為activeSegment,然后再執行刪除操作。
刪除日志分段時,首先會從日志文件對象中所維護日志分段的跳躍表中移除待刪除的日志分段,以保證沒有線程對這些日志分段進行讀取操作。然后將日志分段文件添加上“.deleted”的后綴,當然也包括日志分段對應的索引文件。最后交由一個以“delete-file”命名的延遲任務來刪除這些“.deleted”為后綴的文件,這個任務的延遲執行時間可以通過file.delete.delay.ms參數來設置,默認值為60000,即1分鐘。
2. 基于日志大小
日志刪除任務會檢查當前日志的大小是否超過設定的閾值retentionSize來尋找可刪除的日志分段的文件集合deletableSegments,參考下圖所示。retentionSize可以通過broker端參數log.retention.bytes來配置,默認值為-1,表示無窮大。注意log.retention.bytes配置的是日志文件的總大小,而不是單個的日志分段的大小,一個日志文件包含多個日志分段。
基于日志大小的保留策略與基于時間的保留策略類似,其首先計算日志文件的總大小size和retentionSize的差值diff,即計算需要刪除的日志總大小,然后從日志文件中的第一個日志分段開始進行查找可刪除的日志分段的文件集合deletableSegments。查找出deletableSegments之后就執行刪除操作,這個刪除操作和基于時間的保留策略的刪除操作相同,這里不再贅述。
3. 基于日志起始偏移量
一般情況下日志文件的起始偏移量logStartOffset等于第一個日志分段的baseOffset,但是這并不是絕對的,logStartOffset的值可以通過DeleteRecordsRequest請求、日志的清理和截斷等操作修改。
基于日志起始偏移量的刪除策略的判斷依據是某日志分段的下一個日志分段的起始偏移量baseOffset是否小于等于logStartOffset,若是則可以刪除此日志分段。參考上圖,假設logStartOffset等于25,日志分段1的起始偏移量為0,日志分段2的起始偏移量為11,日志分段3的起始偏移為23,那么我們通過如下動作收集可刪除的日志分段的文件集合deletableSegments:
收集完可刪除的日志分段的文件集合之后的刪除操作同基于日志大小的保留策略和基于時間的保留策略相同,這里不再贅述。
歡迎跳轉到本文的原文鏈接:https://honeypps.com/mq/log-deletion-of-kafka-log-retention/
歡迎支持筆者新作:《深入理解Kafka:核心設計與實踐原理》和《RabbitMQ實戰指南》,同時歡迎關注筆者的微信公眾號:朱小廝的博客。
總結
以上是生活随笔為你收集整理的Kafka日志清理之Log Deletion的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Kafka消息格式中的变长字段(Vari
- 下一篇: Kafka日志清理之Log Compac