日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

面试官:你对Kafka比较熟? 那说说kafka日志段如何读写的吧?

發布時間:2025/3/21 编程问答 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 面试官:你对Kafka比较熟? 那说说kafka日志段如何读写的吧? 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

引子

之所以寫這篇文章是因為之前面試時候被面試官問到(倒)了,面試官說:“你說你對Kafka比較熟?看過源碼? 那說說kafka日志段如何讀寫的吧?”

我心里默默的說了句 “擦…我說看過一點點源碼,不是億點點。早知道不提這句了!”,那怎么辦呢,只能回家等通知了啊。

但是為了以后找回場子,咱也不能坐以待斃,日拱一卒從一點點到億點點。今天我們就來看看源碼層面來Kafka日志段的是如何讀寫的。

Kafka的存儲結構

總所周知,Kafka的Topic可以有多個分區,分區其實就是最小的讀取和存儲結構,即Consumer看似訂閱的是Topic,實則是從Topic下的某個分區獲得消息,Producer也是發送消息也是如此。

topic-partition關系

上圖是總體邏輯上的關系,映射到實際代碼中在磁盤上的關系則是如下圖所示:

每個分區對應一個Log對象,在磁盤中就是一個子目錄,子目錄下面會有多組日志段即多Log Segment,每組日志段包含:消息日志文件(以log結尾)、位移索引文件(以index結尾)、時間戳索引文件(以timeindex結尾)。其實還有其它后綴的文件,例如.txnindex、.deleted等等。篇幅有限,暫不提起。

以下為日志的定義

以下為日志段的定義

indexIntervalBytes可以理解為插了多少消息之后再建一個索引,由此可以看出Kafka的索引其實是稀疏索引,這樣可以避免索引文件占用過多的內存,從而可以在內存中保存更多的索引。對應的就是Broker 端參數log.index.interval.bytes?值,默認4KB。

實際的通過索引查找消息過程是先通過offset找到索引所在的文件,然后通過二分法找到離目標最近的索引,再順序遍歷消息文件找到目標文件。這波操作時間復雜度為O(log2n)+O(m),n是索引文件里索引的個數,m為稀疏程度。

這就是空間和時間的互換,又經過數據結構與算法的平衡,妙啊!

再說下rollJitterMs,這其實是個擾動值,對應的參數是log.roll.jitter.ms,這其實就要說到日志段的切分了,log.segment.bytes,這個參數控制著日志段文件的大小,默認是1G,即當文件存儲超過1G之后就新起一個文件寫入。這是以大小為維度的,還有一個參數是log.segment.ms,以時間為維度切分。

那配置了這個參數之后如果有很多很多分區,然后因為這個參數是全局的,因此同一時刻需要做很多文件的切分,這磁盤IO就頂不住了啊,因此需要設置個rollJitterMs,來岔開它們。

怎么樣有沒有聯想到redis緩存的過期時間?過期時間加個隨機數,防止同一時刻大量緩存過期導致緩存擊穿數據庫??纯粗R都是通的啊!

日志段的寫入

1、判斷下當前日志段是否為空,空的話記錄下時間,來作為之后日志段的切分依據

2、確保位移值合法,最終調用的是AbstractIndex.toRelative(..)方法,即使判斷offset是否小于0,是否大于int最大值。

3、append消息,實際上就是通過FileChannel將消息寫入,當然只是寫入內存中及頁緩存,是否刷盤看配置。

4、更新日志段最大時間戳和最大時間戳對應的位移值。這個時間戳其實用來作為定期刪除日志的依據

5、更新索引項,如果需要的話(bytesSinceLastIndexEntry > indexIntervalBytes)

最后再來個流程圖

消息寫入流程

日志段的讀取

1、根據第一條消息的offset,通過OffsetIndex找到對應的消息所在的物理位置和大小。

2、獲取LogOffsetMetadata,元數據包含消息的offset、消息所在segment的起始offset和物理位置

3、判斷minOneMessage是否為true,若是則調整為必定返回一條消息大小,其實就是在單條消息大于maxSize的情況下得以返回,防止消費者餓死

4、再計算最大的fetchSize,即(最大物理位移-此消息起始物理位移)和adjustedMaxSize的最小值(這波我不是很懂,因為以上一波操作adjustedMaxSize已經最小為一條消息的大小了)

5、調用?FileRecords?的?slice?方法從指定位置讀取指定大小的消息集合,并且構造FetchDataInfo返回

再來個流程圖:

消息讀取流程

小結

從哪里跌倒就從哪里爬起來對吧,這波操作下來咱也不怕下次遇到面試官問了。

區區源碼不過爾爾,哈哈哈哈(首先得要有氣勢)

實際上這只是Kafka源碼的冰山一角,長路漫漫。雖說Kafka Broker都是由Scala寫的,不過語言不是問題,這不看下來也沒什么難點,注釋也很豐富。遇到不知道的語法小查一下搞定。

所以強烈建議大家入手源碼,從源碼上理解。今天說的?append?和?read?是很核心的功能,但一看也并不復雜,所以不要被源碼這兩個字嚇到了。

看源碼可以讓我們深入的理解內部的設計原理,精進我們的代碼功力(經常看著看著,我擦還能這么寫)。當然還有系統架構能力。

然后對我而言最重要的是可以裝逼了(哈哈哈)。

情景劇

老白正目不轉睛盯著監控大屏,“為什么?為什么Kafka Broker物理磁盤 I/O 負載突然這么高?”。寥寥無幾的秀發矗立在老白的頭上,顯得如此的無助。

“是不是設置了?log.segment.ms參數 ?試試?log.roll.jitter.ms吧”,老白抬頭間我已走出了辦公室,留下了一個偉岸的背影和一顆锃亮的光頭!

“我變禿了,也變強了”

總結

以上是生活随笔為你收集整理的面试官:你对Kafka比较熟? 那说说kafka日志段如何读写的吧?的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。