天天看點

零拷貝技術 與 sendfile

願打開此篇對你有所幫助。
零拷貝技術 與 sendfile

曾經的 I/O 過程

弊端分析

解決方案

弊端

現成應用場景

危險!!!

零拷貝技術 與 sendfile

可以看到,整個資料的傳輸過程,都要需要 CPU 親自參與搬運資料的過程,而且這個過程,CPU 是不能做其他事情的。

DMA 技術,也就是直接記憶體通路(Direct Memory Access) 技術。

在進行 I/O 裝置和記憶體的資料傳輸的時候,資料搬運的工作全部交給 DMA 控制器,而 CPU 不再參與任何與資料搬運相關的事情,這樣 CPU 就可以去處理别的事務。

零拷貝技術 與 sendfile
零拷貝技術 與 sendfile

四次上下文切換 + 四次拷貝。

我就傳一份資料,整這麼麻煩。

在 Linux 核心版本 2.1 中,提供了一個專門發送檔案的系統調用函數 sendfile(),函數形式如下:

零拷貝技術 與 sendfile

如果網卡支援 SG-DMA(The Scatter-Gather Direct Memory Access)技術,我們可以進一步減少通過 CPU 把核心緩沖區裡的資料拷貝到 socket 緩沖區的過程。

檢查一下,這一步我來講,不要去百度了,一個抄一個,都沒有親測,看着就煩。

零拷貝技術 與 sendfile

注意看你的網卡叫什麼名字,不一定就 eth0.

于是,從 Linux 核心 2.4 版本開始起,對于支援網卡支援 SG-DMA 技術的情況下, sendfile() 系統調用的過程發生了點變化。

零拷貝技術 與 sendfile

這就是所謂的零拷貝(Zero-copy)技術,因為我們沒有在記憶體層面去拷貝資料,也就是說全程沒有通過 CPU 來搬運資料,所有的資料都是通過 DMA 來進行傳輸的。

1、卡夫卡

2、nginx(我就是從nginx源碼裡看到sendfile,于是寫了這一篇)

在傳輸大檔案(GB 級别的檔案)的時候,PageCache 會不起作用,那就白白浪費 DMA 多做的一次資料拷貝,造成性能的降低,即使使用了 PageCache 的零拷貝也會損失性能。

由于檔案太大,可能某些部分的檔案資料被再次通路的機率比較低,這樣就會帶來 2 個問題:

是以,針對大檔案的傳輸,不應該使用 PageCache,也就是說不應該使用零拷貝技術,因為可能由于 PageCache 被大檔案占據,而導緻「熱點」小檔案無法利用到 PageCache,這樣在高并發的環境下,會帶來嚴重的性能問題。

在高并發的場景下,針對大檔案的傳輸的方式,應該使用「異步 I/O + 直接 I/O」來替代零拷貝技術。

零拷貝技術 與 sendfile

如果不是高并發的大檔案IO,我選擇臨時起個線程。

繼續閱讀