對零複製的理解 zero-copy

一般讀取數據 先是從磁盤複製---->內核態模式中的buffer--->cpu控制將內核態buffer的數據copy到用戶態模式 這是讀取的過程

如下圖:

下面是寫入網絡的過程:

先從用戶態中的buffer獲取到數據------>內核態的socket buffer----->網絡設備中傳送

從上面的過程可以看出,數據白白從kernel模式到user模式走了一圈,浪費了2次copy(第一次,從kernel模式拷貝到user模式;第二次從user模式再拷貝回kernel模式,即上面4次過程的第2和3步驟。)。而且上面的過程中kernel和user模式的上下文的切換也是4次。

下面就說說今天的主角 zero-copy

Zero-Copy技術省去了將操作系統的read buffer拷貝到程序的buffer,以及從程序buffer拷貝到socket buffer的步驟,直接將read buffer拷貝到socket buffer. Java NIO中的FileChannal.transferTo()方法就是這樣的實現,這個實現是依賴於操作系統底層的sendFile()實現的。

linux內核版本2.4下的實現

  1. 將文件拷貝到kernel buffer中;

  2. 向socket buffer中追加當前要發生的數據在kernel buffer中的位置和偏移量;

  3. 根據socket buffer中的位置和偏移量直接將kernel buffer的數據copy到網卡設備(protocol engine)

   中經過上述過程,數據只經過了2次copy就從磁盤傳送出去了。這個纔是真正的Zero-Copy(這裏的零拷貝是針對kernel來講的,數據在kernel模式下是Zero-Copy)。正是Linux2.4的內核做了改進,Java中的TransferTo()實現了Zero-Copy,如下圖:

netty和kafaka 就是使用了這個原理

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章