引言
本文簡單論述零複製技術,為的後續文章中為啥Kafka比RocketMQ快,其中就有一個根本原因之一,kafka 使用了零複製技術,而RocketMQ沒有。故此本文先簡單打基礎。
正文
零複製(Zero-Copy)是一種計算機操作,它減少了CPU的負載,因為資料不需要從一個記憶體區域複製到另一個記憶體區域。 在傳統的數據傳輸操作中,資料通常會在使用者空間和核心空間之間進行多次複製,這不僅消耗CPU週期,還增加了系統的延遲。 在檔案傳輸的上下文中,零複製技術可以直接從檔案系統快取(頁快取)傳輸資料到網路介面,而無需將資料複製到使用者空間緩衝區中。 這通常是透過作業系統提供的特定系統呼叫來實現的,
如Linux中的sendfile
系統呼叫。
下面是一個傳統數據傳輸與零複製傳輸的對比:
傳統數據傳輸流程(多次複製):
從磁碟讀取資料到核心空間的緩衝區。
從核心空間複製資料到使用者空間的緩衝區。
從使用者空間緩衝區複製資料回核心空間的socket緩衝區。
從socket緩衝區將數據傳輸到網路。
在這個過程中,資料在使用者空間和核心空間之間被複制了兩次,增加了CPU的工作負擔。
零複製數據傳輸流程(減少複製):
從磁碟讀取資料到核心空間的頁快取。
直接從頁快取傳輸資料到網路介面。
在零複製流程中,資料不需要複製到使用者空間,也不需要從使用者空間複製回核心空間,從而減少了CPU的負擔,降低了系統呼叫的開銷,減少了上下文切換,提高了數據傳輸的效率。
零複製技術在高效能網路應用中非常重要,特別是在需要高速傳輸大量資料的場景,如檔案伺服器、資料庫、訊息佇列系統(如Kafka)等。使用零複製可以顯著提高這些應用的效能。
mmap
和 sendfile
是兩種常用的零複製技術,它們各自有不同的用途和工作原理。下面詳細解釋這兩種系統呼叫:
mmap
mmap
(記憶體對映)系統呼叫允許應用程式將檔案或裝置的內容對映到程序的地址空間。這意味著檔案可以被當作記憶體陣列來訪問,而無需使用傳統的 read
和 write
系統呼叫。 mmap
的工作原理如下:
應用程式呼叫
mmap
,請求將檔案對映到其虛擬地址空間。作業系統建立一段虛擬記憶體區域,並將這段記憶體與檔案內容關聯起來,但此時並不立即載入檔案資料。
當應用程式訪問這段記憶體時,如果所需資料尚未載入,則會觸發一個頁面錯誤(page fault)。
頁面錯誤處理程式負責將磁碟上的資料載入到實體記憶體中,然後對映到程序的虛擬地址空間。
一旦資料被載入,應用程式就可以像訪問普通記憶體一樣訪問檔案內容,而無需進行資料複製。
mmap
的優點是可以透過記憶體訪問檔案,減少了將檔案內容讀取到使用者空間緩衝區的需要。但是,mmap
並不總是完全沒有資料複製,因為它依賴於頁快取,所以在某些情況下,如寫操作, 仍然需要將資料從頁快取複製到使用者空間。
mmap 時序圖:
時序圖解釋:
使用者空間(User Space)呼叫
mmap()
系統呼叫。核心空間(Kernel Space)請求記憶體管理器(Memory Manager)為檔案建立一個虛擬記憶體區域(VMA,Virtual Memory Area)。
核心空間將對映區域的指標返回給使用者空間。
使用者空間訪問對映區域,如果需要的資料頁不在記憶體中,則會觸發頁面錯誤(page fault)。
記憶體管理器向檔案系統(File System)請求從檔案載入資料到頁快取(page cache)。
檔案系統將資料載入到頁快取。
記憶體管理器將資料頁對映到程序的地址空間。
使用者空間繼續執行,現在可以直接訪問對映的檔案資料。
sendfile
sendfile
系統呼叫是專門設計用來在兩個檔案描述符之間高效地傳輸資料,常用於將資料從檔案直接傳送到網路套接字。 sendfile
的工作原理如下:
應用程式呼叫
sendfile
並指定原始檔描述符(通常是開啟檔案的描述符)和目標檔案描述符(通常是網路套接字)。作業系統將原始檔的資料讀取到核心空間的頁快取中(如果資料還不在頁快取中)。
然後作業系統直接將資料從頁快取傳輸到目標檔案描述符的傳輸緩衝區,這通常是一個網路套接字的傳送緩衝區。
網路介面負責將資料從套接字緩衝區傳送到網路上。
sendfile
的優點在於它完全避免了使用者空間和核心空間之間的資料複製,因為資料在核心空間內部傳輸。這大大減少了CPU的使用和上下文切換,提高了檔案傳輸的效率。
sendfile 時序圖:
時序圖解釋:
使用者空間(User Space)呼叫
sendfile()
系統呼叫。核心空間(Kernel Space)向檔案系統(File System)請求檔案資料。
檔案系統將檔案資料放入核心的頁快取(page cache)。
核心空間將資料從頁快取複製到網路棧(Network Stack)的套接字緩衝區(socket buffer)。
網路棧負責將資料從套接字緩衝區透過網路傳輸。
傳輸完成後,核心空間將傳送的位元組數返回給使用者空間。
總結來說,mmap
允許檔案以記憶體的形式被訪問,適用於需要隨機訪問檔案資料的情況。而 sendfile
是爲了在檔案和套接字之間快速傳輸資料而設計的,它在處理靜態檔案傳輸到網路客戶端的場景(如Web伺服器)中非常高效。兩者都是零複製技術的實現,它們透過減少不必要的資料複製來提升效能。
結論
零複製技術是提升數據傳輸效率的有效手段之一。透過減少CPU參與的資料複製次數,它不僅提升了效能,還降低了系統的資源消耗。隨著資料中心和雲端計算的發展,零複製技術將繼續在最佳化系統性能方面發揮重要作用。