零拷貝技術 與 sendfile
愿打開此篇對你有所幫助。
(圖片來源網絡)
@[toc]
曾經的 I/O 過程
弊端分析
可以看到,整個數據的傳輸過程,都要需要 CPU 親自參與搬運數據的過程,而且這個過程,CPU 是不能做其他事情的。
解決方案
DMA 技術,也就是直接內存訪問(Direct Memory Access) 技術。
在進行 I/O 設備和內存的數據傳輸的時候,數據搬運的工作全部交給 DMA 控制器,而 CPU 不再參與任何與數據搬運相關的事情,這樣 CPU 就可以去處理別的事務。
弊端
四次上下文切換 + 四次拷貝。
我就傳一份數據,整這么麻煩。
解決方案
在 Linux 內核版本 2.1 中,提供了一個專門發送文件的系統調用函數 sendfile(),函數形式如下:
#include
如果網卡支持 SG-DMA(The Scatter-Gather Direct Memory Access)技術,我們可以進一步減少通過 CPU 把內核緩沖區里的數據拷貝到 socket 緩沖區的過程。
檢查一下,這一步我來講,不要去百度了,一個抄一個,都沒有親測,看著就煩。
注意看你的網卡叫什么名字,不一定就 eth0.
于是,從 Linux 內核 2.4 版本開始起,對于支持網卡支持 SG-DMA 技術的情況下, sendfile() 系統調用的過程發生了點變化。
這就是所謂的零拷貝(Zero-copy)技術,因為我們沒有在內存層面去拷貝數據,也就是說全程沒有通過 CPU 來搬運數據,所有的數據都是通過 DMA 來進行傳輸的。
現成應用場景
1、卡夫卡
2、nginx(我就是從nginx源碼里看到sendfile,于是寫了這一篇)
危險?。?!
在傳輸大文件(GB 級別的文件)的時候,PageCache 會不起作用,那就白白浪費 DMA 多做的一次數據拷貝,造成性能的降低,即使使用了 PageCache 的零拷貝也會損失性能。
由于文件太大,可能某些部分的文件數據被再次訪問的概率比較低,這樣就會帶來 2 個問題:
PageCache 由于長時間被大文件占據,其他「熱點」的小文件可能就無法充分使用到 PageCache,于是這樣磁盤讀寫的性能就會下降了; PageCache 中的大文件數據,由于沒有享受到緩存帶來的好處,但卻耗費 DMA 多拷貝到 PageCache 一次;
所以,針對大文件的傳輸,不應該使用 PageCache,也就是說不應該使用零拷貝技術,因為可能由于 PageCache 被大文件占據,而導致「熱點」小文件無法利用到 PageCache,這樣在高并發的環境下,會帶來嚴重的性能問題。
解決方案
在高并發的場景下,針對大文件的傳輸的方式,應該使用「異步 I/O + 直接 I/O」來替代零拷貝技術。
如果不是高并發的大文件IO,我選擇臨時起個線程。
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。