Kafka 如何實現每秒百萬級高併發寫入?
大家好,我是 mikechen。
磁盤順序寫
Kafka 採用順序寫入日誌文件的方式,這種方式比隨機寫入快得多。
爲什麼採用磁盤順序寫要快很多呢?如下圖所示:
一般,完成一次磁盤 I/O(輸入 / 輸出)操作,通常需要經歷以下三個主要步驟:尋道、旋轉、和數據傳輸。
-
尋道:磁頭從當前位置,移動到包含目標數據的軌道,這個過程可能需要幾毫秒時間;
-
旋轉:盤片旋轉直到目標數據正好位於磁頭下方,通常也需要幾毫秒時間;
-
傳輸:磁頭讀取、或寫入數據,數據通過磁盤接口傳輸到主存儲器、或從主存儲器傳輸到磁盤。
由於尋道時間、和旋轉延遲,是機械硬盤中較爲耗時的部分,如果減少這兩者的操作,就會極大的提升數據 “讀和寫” 的性能。
怎麼才能減少呢?那就是採用順序寫,如下圖所示:
採用順序寫入,可以極大的減少了磁頭移動、和盤片旋轉所需的時間,而且,數據還可以連續地寫入、或讀取數據。
即使在固態硬盤(SSD)上,順序寫入也優於隨機寫入,儘管 SSD 沒有機械運動部件,但其內部的閃存塊管理、和寫入放大效應也會使得順序寫入更加高效。
零拷貝
Kafka 的零拷貝技術是其高性能的關鍵因素之一,因爲:零拷貝技術通過減少數據在內存中的複製次數,從而,提高了數據傳輸的效率。
在傳統的數據傳輸過程中,數據從磁盤讀取到應用程序的內存,再從應用程序的內存,寫入到網絡緩衝區,這涉及多次數據拷貝。
如下圖所示:
上圖的:“1”、和 “2” 就是涉及到多次數據拷貝,如果能減少拷貝次數,也必然會提升性能。
優化後,如下圖所示:
減少了:“1”、和 “2” 的數據拷貝,直接從 os cache 把數據發送到了網卡,也就是說:數據直接從內核空間的文件緩存傳輸到網絡緩衝區。
這樣就減少了數據拷貝的次數,不需要:把 ”os cache 裏的數據拷貝到應用緩存 “,再從” 應用緩存拷貝到 Socket 緩存“,減少了兩次拷貝。
這樣,Kafka 採用零拷貝技術,通過減少數據在內存中的複製次數,降低了 CPU 和內存帶寬的負擔,也顯著提高了數據傳輸性能。
頁緩存技術
Kafka 在寫入磁盤文件時,可以利用操作系統的頁緩存機制,從而實現先寫入內存(即操作系統緩存)。
然後由操作系統,異步地將數據刷寫到磁盤,這種方法提高了寫入性能,減少了延遲。
如下圖所示:
大致流程如下:
1、應用程序寫入數據
Kafka 調用文件系統接口,將數據寫入文件。
2、操作系統緩存
操作系統將數據寫入頁緩存,而不是立即寫入磁盤。
3、異步刷寫
操作系統在後臺異步地將頁緩存中的數據寫入磁盤,這通常由操作系統的髒頁寫回(Dirty Page Writeback)機制來完成,定期將髒頁寫入磁盤。
通過以上利用頁緩存步驟,Kafka 的寫入操作可以快速完成,減少了寫入延遲,提高了系統的吞吐量。
內存映射文件
Kafka 利用內存映射文件(Memory-Mapped Files),將磁盤上的數據直接映射到內存中,從而加快數據的訪問速度。
使用操作系統提供的 mmap 系統調用,將文件的一部分、或全部內容,映射到進程的虛擬內存地址空間。
映射完成後,文件內容可以像訪問普通內存一樣直接進行讀寫操作,無需顯式的文件 I/O 調用。
這種方式,利用操作系統的虛擬內存管理機制來高效地管理大量數據。
除此之外,Kafka 還優化了:消息存儲格式、協議、集羣... 等,從而做到了如此高性能。
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/UJ7HxjO8GXSRK-zwDOB42g