首頁 > 軟體

架構篇:Kafka和RokcetMQ高效能底層支撐技術零拷貝原理詳解

2021-05-30 13:02:07

「來源: |java架構師進階之路 ID:gh_a39b0d322dde」

眾所周知,Kafka和RocketMQ高效能除了本身的某些設計之後,最重要的是實現零拷貝技術。通過採用零拷貝大大提供了應用效能,減少了核心和使用者模式之間的上下文切換次數。那麼什麼是零拷貝,如何實現零拷貝呢?

什麼是零拷貝

WIKI中對其有如下定義:

"Zero-copy" describes computer operations in which the CPU does not perform the task of copying data from one memory area to another.

從WIKI的定義中,我們看到「零拷貝」是指計算機操作的過程中,CPU不需要為資料在記憶體之間的拷貝消耗資源。而它通常是指計算機在網路上傳送檔案時,不需要將檔案內容拷貝到使用者空間(User Space)而直接在核心空間(Kernel Space)中傳輸到網路的方式。

零拷貝給我們帶來的好處

減少甚至完全避免不必要的CPU拷貝,從而讓CPU解脫出來去執行其他的任務減少記憶體頻寬的佔用通常零拷貝技術還能夠減少使用者空間和作業系統核心空間之間的上下文切換零拷貝的實現

零拷貝實際的實現並沒有真正的標準,取決於作業系統如何實現這一點。零拷貝完全依賴於作業系統。作業系統支援,就有;不支援,就沒有。不依賴Java本身。

傳統I/O

我們以檔案下載為例。

在傳統LINUX環境中,分為使用者空間和核心空間。使用者空間可以理解為JVM,JVM是沒有權利去呼叫啟動對程序的許可權的,因為這部分內容是CPU的核心空間控制。所以,如果要下載檔案,JVM先啟動一個執行緒首先得去核心空間申請這一個請求,進行read操作,當核心空間從磁碟開始讀檔案時,根據LINUX內部機制,會首先將資料放到頁快取中,當頁快取達到儲存容量後,進行刷盤,統一將所有資料刷到記憶體,這時JVM讀到資料後,進行後續的寫操作。同樣,對應的socket層和網路是LINX控制,還需要繼續拷貝資料導socket和網路層將資料寫到本地。如下圖:

由圖可知,上面過程產生了四次資料拷貝,而此過程,我們沒有對檔案內容進行任何修改,那麼,在核心空間和使用者空間中來回拷貝資料無意是對效能的一種浪費,而零拷貝就是為了解決這種低效性。

什麼是零拷貝技術?

零拷貝主要的任務就是避免CPU將資料從一塊儲存拷貝到另外一塊儲存,主要就是利用各種零拷貝技術,避免讓CPU做大量的資料拷貝任務,減少不必要的拷貝,或者讓別的元件來做這一類簡單的資料傳輸任務,讓CPU解脫出來專注於別的任務。這樣就可以讓系統資源的利用更加有效。

原理是磁碟上的資料會通過DMA被拷貝的核心緩衝區,接著作業系統會把這段核心緩衝區與應用程式共享(可以理解為Kafka或RocketMQ通過某種技術手段進行了對映),這樣就不需要把核心緩衝區的內容往使用者空間拷貝。應用程式再呼叫write(),作業系統直接將核心緩衝區的內容拷貝到socket緩衝區中,這一切都發生在核心態,最後,socket緩衝區再把資料發到網卡去。

原理如下:

解釋:

mmap是一種記憶體對映檔案的方法。

mmap將一個檔案或者其它物件對映進記憶體。檔案被對映到多個頁上,如果檔案的大小不是所有頁的大小之和,最後一個頁不被使用的空間將會清零。mmap在使用者空間對映呼叫系統中作用很大。

對於零拷貝來說,現在應用範圍越來越廣,比如NIO等,其實對於Kafka和RokectMQ來說,零拷貝技術只是其提高效能的一種手段,關於其他的各自獨有設計,會後續持續更新,歡迎關注。

以上為全部內容。


IT145.com E-mail:sddin#qq.com