sendfile是如何提高效能的

2021-07-26 06:27:27 字數 1559 閱讀 7118

現在流行的 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效能的原因。

SQL 提高效能

參考部落格 非常感謝博主分享。1.set nocount on 關閉行基數資訊,減少網路通訊,提高程式效能。2.count 1 count 2 count name count 前三種效果一樣,count 找出最短的列,所以建議用count 1 效率高。3.with nolock 大量的查詢,會導致...

CSS效能分析,如何優化CSS提高效能

其實,不規範的css會導致很多效能問題,這些問題可能在一些小的專案中不夠明顯,但是在大型專案中就會顯現出來。在優化css之前我們需要了解下css是怎麼進行工作的,我們都知道css是由選擇器,屬性和屬性值構成的。我們可能會這樣寫上一行 css con loulan1 p span html div c...

CSS效能分析,如何優化CSS提高效能

其實,不規範的css會導致很多效能問題,這些問題可能在一些小的專案中不夠明顯,但是在大型專案中就會顯現出來。在優化css之前我們需要了解下css是怎麼進行工作的,我們都知道css是由選擇器,屬性和屬性值構成的。我們可能會這樣寫上一行 css con loulan1 p span html div c...