Kafka Note(三)高吞吐王牌殺手锏

(三)kafka高吞吐王牌殺手锏

A. 順序讀寫

  • 影響因素

    • 機(jī)械硬盤的io有兩個(gè)階段,分別為尋址 & 寫入。
    • 尋址:物理動(dòng)作,通過旋轉(zhuǎn)和磁臂找到對(duì)應(yīng)扇區(qū),其動(dòng)作較慢,耗時(shí)是毫秒級(jí)。
    • 寫入:數(shù)據(jù)的寫入階段很快,非優(yōu)化重點(diǎn)方向。
  • 核心效果:producer傾倒消息時(shí)是不斷追加到文件的形式,因此kafka利用追加寫入完成磁盤順序讀寫,減少磁盤磁頭尋道時(shí)間,遠(yuǎn)快于隨機(jī)讀寫。

  • 補(bǔ)充說明:linux io調(diào)度有4種方法

    • NOOP(先進(jìn)先出的隊(duì)列)
    • CFQ(默認(rèn)方法,根據(jù)io請(qǐng)求的地址排序,但是這導(dǎo)致小的io動(dòng)作如果地址靠后的話就需要一直等待)
    • DEADLINE(CFQ的升級(jí)版,設(shè)置了等待時(shí)間的上限)
    • ANTICIPATORY(每個(gè)io請(qǐng)求都等6ms,如果這個(gè)時(shí)間內(nèi)收到了地址相近的操作就合并一起)

B. 零拷貝zero copy

  • 核心效果:基于linux的send file命令,減少內(nèi)核態(tài)到用戶態(tài)之間的拷貝。

  • 具體流程

    1. 在內(nèi)核態(tài)kernel中操作,將數(shù)據(jù)從disk復(fù)制到memory buffer,在kafka的場景下,其實(shí)數(shù)據(jù)從disk走到了page cache;
    2. 從page cache中把數(shù)據(jù)傳遞到socket buffer,最后給到nic buffer發(fā)出去。
  • 優(yōu)勢:上述兩步操作都在內(nèi)核態(tài)kernel中完成,若沒有send file機(jī)制數(shù)據(jù)需要從第一步的page cache拷貝到用戶態(tài)的kafka應(yīng)用中,然后再從kafka應(yīng)用中拷貝到內(nèi)核態(tài)的socket buffer中,多了兩次拷貝動(dòng)作。

C. 頁緩存page cache

  • 核心效果:數(shù)據(jù)在內(nèi)存memory中的讀寫速度高于在磁盤disk下的讀寫速度,而page cache就是利用內(nèi)存空間來實(shí)現(xiàn)提速的。
  • 具體流程:結(jié)合上方的zero copy,kafka完成了數(shù)據(jù)傳輸?shù)摹翱罩薪恿Α薄?
    1. 生產(chǎn)者將數(shù)據(jù)發(fā)送到broker;
    2. broker將數(shù)據(jù)先存至page cache,再刷入磁盤;
    3. 消費(fèi)者此時(shí)若拉取數(shù)據(jù),數(shù)據(jù)可基于send file,在broker上直接從page cache中到socket buffer,再從nic buffer送出;
    4. 消費(fèi)者憑借zero copy,結(jié)合page cache的加速更快獲得數(shù)據(jù)。
  • 注意點(diǎn):kafka會(huì)用到大量memory作為page cache,所以linux的swap空間會(huì)被使用起來,一些不活躍的進(jìn)程被放入了swap。

D. 分區(qū)機(jī)制partition

1. 分區(qū)過多會(huì)破壞Kafka追加寫

  • partition底層對(duì)應(yīng)的是一個(gè)或多個(gè)segment文件,若分區(qū)過多會(huì)導(dǎo)致有大量segment文件。雖然每個(gè)文件單獨(dú)看都是追加寫的模式,但是系統(tǒng)宏觀角度下會(huì)切換寫入多個(gè)segment文件,這樣尋址成本等于是隨機(jī)io(rocketMQ對(duì)此作了優(yōu)化,所有分區(qū)數(shù)據(jù)寫入一個(gè)commitLog)。
  • 若kafka部署在云盤或者使用ssd就不用擔(dān)心該問題,前者走帶寬,后者不需要物理尋址。

2. Kafka數(shù)據(jù)存儲(chǔ)結(jié)構(gòu)

  • Topic & partition:Topic由大量partitions構(gòu)成,利用分布式結(jié)構(gòu)分散在不同broker節(jié)點(diǎn)上增加并行能力,而提升partition可以進(jìn)一步利用并發(fā)能力,隨著增加對(duì)應(yīng)下有消費(fèi)者數(shù)目,盡可能地提升吞吐量。

  • 存儲(chǔ)的微觀單位:每個(gè)partition有單獨(dú)的目錄,目錄下又被具體分為多個(gè)segments,單個(gè)segment由一對(duì)文件——索引文件 & 數(shù)據(jù)文件。默認(rèn)情況下segment的數(shù)據(jù)文件大小為log.segment.bytes=1073741824,即1gb。

    1. 索引文件:0000000.index,其名稱為該段的起始索引號(hào),總體采用是稀疏索引的方式。索引文件由message索引號(hào)(從1開始)和該message的末尾offset組成。

      Message index Message position annotation
      1 0 第一條空的
      3 4597 稀疏index,直接index=3
      6 9807
    2. 數(shù)據(jù)文件:0000000.log,保存上方索引文件對(duì)應(yīng)的數(shù)據(jù)內(nèi)容,由數(shù)據(jù)和position組成。

      message data Message position annotation
      Message1 data part 0 第一條空的
      Message2 data part 2039 數(shù)據(jù)文件不可能稀疏,完整記載末尾的offset是多少
      Message3 data part 4597 對(duì)應(yīng)index=3的情況
      Message4 data part 6830
      Message5 data part 7912
      Message6 data part 9807 對(duì)應(yīng)index=6的情況
  • 刪除機(jī)制

    1. 周期檢查:broker server周期性地檢測和刪除不符合保留條件的segments,具體周期根據(jù)配置的log.retention.check.interval.ms參數(shù),默認(rèn)為5分鐘。
    2. 基于時(shí)間保留:基于配置的log.retention.ms | log.retention.minutes | log.retention.hours(若都配置了,優(yōu)先級(jí)羅列的這個(gè)順序逐級(jí)降低),默認(rèn)168hours(7天)。非激活狀態(tài)下的segment超過這個(gè)時(shí)長后,會(huì)被清理。
    3. 基于文件大小保留:基于log.retention.bytes的配置,目錄下所有segments的數(shù)據(jù)文件大小若大于這個(gè)值,則刪除最早的segment。

E. 其他手段

  • 批量發(fā)送:生產(chǎn)者客戶端緩存消息后批量發(fā)送給broker,消費(fèi)者也批量從broker拉取數(shù)據(jù),減少網(wǎng)絡(luò)上的io次數(shù)。
  • 網(wǎng)絡(luò)瓶頸:kafka的核心性能瓶頸不是cpu、磁盤,而是網(wǎng)絡(luò)帶寬,需盡可能的壓縮數(shù)據(jù)(下個(gè)主題對(duì)kafka的網(wǎng)絡(luò)進(jìn)行了闡述說明)。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容