sendfile 實現零拷貝詳解

2021-06-22 00:02:53 字數 1921 閱讀 8275

2023年11月18日 11:17    供稿中心: 網際網路運營部

摘要:

linux的sendfile()系統呼叫

伺服器響應乙個http請求的步驟如下:

1 把磁碟檔案讀入核心緩衝區

2 從核心緩衝區讀到記憶體

3 處理(靜態資源不需處理)

4 傳送到網絡卡的核心緩衝區(傳送快取)

5 網絡卡傳送資料

資料從第一步中的核心緩衝區到第四步的核心緩衝區白白繞了乙個圈,沒有任何變化浪費了時間。

而sendfile系統呼叫就是來解決這個問題的。sendfile省略了上面的 2、3步,磁碟檔案被直接傳送到了網絡卡的記憶體緩衝區,減少了資料複製和核心態切換的開銷 。

現在流行的 web 伺服器裡面都提供 sendfile 選項用來提高伺服器效能,那到底 sendfile 是什麼,怎麼影響效能的呢?sendfile 實際上是 linux 2.0+ 以後的推出的乙個系統呼叫,web 伺服器可以通過調整自身的配置來決定是否利用 sendfile 這個系統呼叫。先來看一下不用 sendfile 的傳統網路傳輸過程:

read(file, tmp_buf, len);

write(socket, tmp_buf, len);

硬碟 >> kernel buffer >> user buffer >> kernel socket buffer >> 協議棧

一般來說乙個網路應用是通過讀硬碟資料,然後寫資料到 socket 來完成網路傳輸的。上面2行用**解釋了這一點,不過上面2行簡單的**掩蓋了底層的很多操作。來看看底層是怎麼執行上面2行**的:

1、系統呼叫 read() 產生乙個上下文切換:從 user mode 切換到 kernel mode,然後 dma 執行拷貝,把檔案資料從硬碟讀到乙個 kernel buffer 裡。

2、資料從 kernel buffer 拷貝到 user buffer,然後系統呼叫 read() 返回,這時又產生乙個上下文切換:從kernel mode 切換到 user mode。

3、系統呼叫 write() 產生乙個上下文切換:從 user mode 切換到 kernel mode,然後把步驟2讀到 user buffer 的資料拷貝到 kernel buffer(資料第2次拷貝到 kernel buffer),不過這次是個不同的 kernel buffer,這個 buffer 和 socket 相關聯。

4、系統呼叫 write() 返回,產生乙個上下文切換:從 kernel mode 切換到 user mode(第4次切換了),然後 dma 從 kernel buffer 拷貝資料到協議棧(第4次拷貝了)。

上面4個步驟有4次上下文切換,有4次拷貝,我們發現如果能減少切換次數和拷貝次數將會有效提公升效能。在kernel 2.0+ 版本中,系統呼叫 sendfile() 就是用來簡化上面步驟提公升效能的。sendfile() 不但能減少切換次數而且還能減少拷貝次數。

再來看一下用 sendfile() 來進行網路傳輸的過程:

sendfile(socket, file, len);

硬碟 >> kernel buffer (快速拷貝到kernel socket buffer) >> 協議棧

1、系統呼叫 sendfile() 通過 dma 把硬碟資料拷貝到 kernel buffer,然後資料被 kernel 直接拷貝到另外乙個與 socket 相關的 kernel buffer。這裡沒有 user mode 和 kernel mode 之間的切換,在 kernel 中直接完成了從乙個 buffer 到另乙個 buffer 的拷貝。

2、dma 把資料從 kernel buffer 直接拷貝給協議棧,沒有切換,也不需要資料從 user mode 拷貝到 kernel mode,因為資料就在 kernel 裡。

步驟減少了,切換減少了,拷貝減少了,自然效能就提公升了。這就是為什麼說在 nginx 配置檔案裡開啟 sendfile on 選項能提高 web serve r效能的原因。

sendfile函式 零拷貝

零拷貝 零拷貝技術可以減少資料拷貝和共享匯流排操作的次數,消除通訊資料在儲存器之間不必要的中間拷貝過程,有效地提高通訊效率,是設計高速介面通道 實現高速伺服器和路由器的關鍵技術之一。sendfile include ssize t sendfile int out fd,int in fd,off ...

sendfile「零拷貝」和mmap記憶體對映

在學習sendfille之前,我們先來了解一下瀏覽器訪問頁面時,後台伺服器的大致工作流程。下圖是從使用者訪問某個頁面到頁面的顯示這幾秒鐘的時間當中,在後台的整個工作過程。如上圖,黑色箭頭所示的過程,是傳統方式的資料傳輸 第一步 當使用者請求www.test.com index.html網頁時,ngi...

sendfile「零拷貝」和mmap記憶體對映

在學習sendfille之前,我們先來了解一下瀏覽器訪問頁面時,後台伺服器的大致工作流程。下圖是從使用者訪問某個頁面到頁面的顯示這幾秒鐘的時間當中,在後台的整個工作過程。如上圖,黑色箭頭所示的過程,是傳統方式的資料傳輸 第一步 當使用者請求www.test.com index.html網頁時,ngi...