現在流行的 web 伺服器裡面都提供 sendfile 選項用來提高伺服器效能,那到底 sendfile 是什麼,怎麼影響效能的呢?sendfile 實際上是 linux 2.0+ 以後的推出的乙個系統呼叫,web 伺服器可以通過調整自身的配置來決定是否利用 sendfile 這個系統呼叫。先來看一下不用 sendfile 的傳統網路傳輸過程:
read(file, tmp_buf, len);一般來說乙個網路應用是通過讀硬碟資料,然後寫資料到 socket 來完成網路傳輸的。上面2行用**解釋了這一點,不過上面2行簡單的**掩蓋了底層的很多操作。來看看底層是怎麼執行上面2行**的:write(socket, tmp_buf, len);
硬碟 >> kernel buffer >> user buffer >> kernel socket buffer >> 協議棧
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);1、系統呼叫 sendfile() 通過 dma 把硬碟資料拷貝到 kernel buffer,然後資料被 kernel 直接拷貝到另外乙個與 socket 相關的 kernel buffer。這裡沒有 user mode 和 kernel mode 之間的切換,在 kernel 中直接完成了從乙個 buffer 到另乙個 buffer 的拷貝。硬碟 >> kernel buffer (快速拷貝到kernel socket buffer) >> 協議棧
2、dma 把資料從 kernel buffer 直接拷貝給協議棧,沒有切換,也不需要資料從 user mode 拷貝到 kernel mode,因為資料就在 kernel 裡。
步驟減少了,切換減少了,拷貝減少了,自然效能就提公升了。這就是為什麼說在 nginx 配置檔案裡開啟 sendfile on 選項能提高 web serve r效能的原因。(參見:64mb vps 上優化nginx)
sendfile優化檔案拷貝
現在流行的 web 伺服器裡面都提供 sendfile 選項用來提高伺服器效能,那到底 sendfile 是什麼,怎麼影響效能的呢?sendfile 實際上是 linux 2.0 以後的推出的乙個系統呼叫,web 伺服器可以通過調整自身的配置來決定是否利用 sendfile 這個系統呼叫。先來看一下...
sendfile優化檔案拷貝
現在流行的 web 伺服器裡面都提供 sendfile 選項用來提高伺服器效能,那到底 sendfile 是什麼,怎麼影響效能的呢?sendfile 實際上是 linux 2.0 以後的推出的乙個系統呼叫,web 伺服器可以通過調整自身的配置來決定是否利用 sendfile 這個系統呼叫。先來看一下...
sendfile函式 零拷貝
零拷貝 零拷貝技術可以減少資料拷貝和共享匯流排操作的次數,消除通訊資料在儲存器之間不必要的中間拷貝過程,有效地提高通訊效率,是設計高速介面通道 實現高速伺服器和路由器的關鍵技術之一。sendfile include ssize t sendfile int out fd,int in fd,off ...