教面試官ReentrantLock源碼
1212
2025-03-31
在Kafka的數據路徑下有很多.index和.timeindex后綴文件:
.index文件,即Kafka中的位移索引文件
.timeindex文件,即時間戳索引文件。
1 OffsetIndex - 位移索引
1.1 定義
用于根據位移值快速查找消息所在文件位置。
每當Consumer需要從topic分區的某位置開始讀消息時,Kafka就會用OffsetIndex直接定位物理文件位置,避免從頭讀取消息的I/O性能開銷。
不同索引類型保存不同的 K.V 對。OffsetIndex的K即消息的相對位移,V即保存該消息的日志段文件中該消息第一個字節的物理文件位置。
相對位移
AbstractIndex類中的抽象方法entrySize定義了單個K.V對所用的字節數。
OffsetIndex的entrySize就是8,如OffsetIndex.scala中定義的那樣:
相對位移是個Integer,4字節,物理文件位置也是一個Integer,4字節,因此共8字節。
Kafka的消息位移值是一個長整型(Long),應占8字節。在保存OffsetIndex的K.V對時,Kafka做了一些優化。每個OffsetIndex對象在創建時,都已保存了對應日志段對象的起始位移,因此,OffsetIndex無需保存完整8字節位移值。實際上,只需保存與起始位移的差值,該差值整型存儲足矣。這種設計就讓OffsetIndex每個索引項都節省4字節。
假設某一索引文件保存1000個索引項,使用相對位移值就能節省大約4M。
AbstractIndex定義了relativeOffset方法
將一個Long位移值轉換成相對偏移
真正的轉換
讀取OffsetIndex時,還需將相對偏移值還原成之前的完整偏移。
parseEntry:構造OffsetPosition所需的Key和Value
該方法返回OffsetPosition類型。因為該類的倆方法分別返回索引項的K、V。
physical
寫索引項 - append
通過Long位移值和Integer物理文件位置參數,然后向mmap寫入相對位移值、物理文件位置
Truncation 截斷
將索引文件內容直接裁剪掉部分。比如,OffsetIndex索引文件中當前保存100個索引項,現在只想保留最開始40個索引項。
truncateToEntries
使用OffsetIndex
OffsetIndex被用來快速定位消息所在的物理文件位置,那么必然需定義一個方法執行對應的查詢邏輯。這個方法就是lookup。
該方法返回的,是不大于給定位移值targetOffset的最大位移值,以及對應的物理文件位置。你大致可以把這個方法,理解為位移值的FLOOR函數。
2 TimeIndex - 時間戳索引
2.1 定義
用于根據時間戳快速查找特定消息的位移值。
TimeIndex保存<時間戳,相對位移值>對:
時間戳需長整型存儲
相對偏移值使用Integer存儲
因此,TimeIndex單個索引項需要占12字節。
存儲同數量索引項,TimeIndex比OffsetIndex占更多磁盤空間。
2.2 寫索引
maybeAppend
向TimeIndex寫索引的主體邏輯,是向mmap分別寫入時間戳和相對偏移值。
除校驗偏移值的單調增加性之外,TimeIndex還會確保順序寫入的時間戳也單調增加。
不單調增加會咋樣?
向TimeIndex索引文件中寫入一個過期時間戳和位移,就會導致消費端程序混亂。因為,當消費者端程序根據時間戳信息去過濾待讀取消息時,它讀到了這個過期時間戳并拿到錯誤位移值,于是返回錯誤數據。
3 總結及 FAQ
雖然OffsetIndex和TimeIndex是不同類型索引,但Kafka內部把二者結合使用。通常先使用TimeIndex尋找滿足時間戳要求的消息位移值,然后再利用OffsetIndex定位該位移值所在的物理文件位置。因此,它們其實是協作關系。
二者的 broker 端參數都是log.index.size.max.bytes
為什么需要一起使用,消費者不是根據Offset找到對于位置值開始消費就好嗎?而且結合使用性能也應該降低吧?
沒錯。不過一般情況下消費者并不是直接能夠定位目標offset,相反地它是通過時間戳先找到目標offset。
不要對索引文件做任何修改!擅自重命名索引文件可能導致Broker崩潰無法啟動的場景。雖然Kafka能重建索引,但隨意刪除索引文件很危險!
建立分區初始化的時候,log-segment的位移索引和時間索引文件將近有10M的數據?
里面為空,只是預分配了10MB的空間
kafka記錄消費者的消費offset是對消費者組,還是對單個消費者?比如一個消費者組中新加入一個消費者,分區重新分配,那新加入的消費者是從哪里開始消費?
針對消費者組,或者說針對每個group id。保存的是
Kafka沒有提供延時消息機制,只能自己實現的哈。
Kafka
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。