配置示例
http {
# other directives
sendfile on;
# other directives
}
指令說明
語法: sendfile on | off;
默認(rèn)值: sendfile off;
上下文: http,server,location,if in location
指定是否使用sendfile系統(tǒng)調(diào)用來傳輸文件。
sendfile系統(tǒng)調(diào)用在兩個文件描述符之間直接傳遞數(shù)據(jù)(完全在內(nèi)核中操作),從而避免了數(shù)據(jù)在內(nèi)核緩沖區(qū)和用戶緩沖區(qū)之間的拷貝,操作效率很高,被稱之為零拷貝。
原理解釋
read/write
在傳統(tǒng)的文件傳輸方式(read、write/send方式),具體流程細(xì)節(jié)如下:
- 調(diào)用read函數(shù),文件數(shù)據(jù)拷貝到內(nèi)核緩沖區(qū)
- read函數(shù)返回,數(shù)據(jù)從內(nèi)核緩沖區(qū)拷貝到用戶緩沖區(qū)
- 調(diào)用write/send函數(shù),將數(shù)據(jù)從用戶緩沖區(qū)拷貝到內(nèi)核socket緩沖區(qū)
- 數(shù)據(jù)從內(nèi)核socket緩沖區(qū)拷貝到協(xié)議引擎中
在這個過程當(dāng)中,文件數(shù)據(jù)實(shí)際上是經(jīng)過了四次拷貝操作:
硬盤—>內(nèi)核緩沖區(qū)—>用戶緩沖區(qū)—>內(nèi)核socket緩沖區(qū)—>協(xié)議引擎
sendfile
sendfile系統(tǒng)調(diào)用則提供了一種減少拷貝次數(shù),提升文件傳輸性能的方法。
- sendfile系統(tǒng)調(diào)用利用DMA引擎將文件數(shù)據(jù)拷貝到內(nèi)核緩沖區(qū),之后數(shù)據(jù)被拷貝到內(nèi)核socket緩沖區(qū)中
- DMA引擎將數(shù)據(jù)從內(nèi)核socket緩沖區(qū)拷貝到協(xié)議引擎中
這里沒有用戶態(tài)和內(nèi)核態(tài)之間的切換,也沒有內(nèi)核緩沖區(qū)和用戶緩沖區(qū)之間的拷貝,大大提升了傳輸性能。
這個過程數(shù)據(jù)經(jīng)歷的拷貝操作如下:
硬盤—>內(nèi)核緩沖區(qū)—>內(nèi)核socket緩沖區(qū)—>協(xié)議引擎
帶有DMA收集拷貝功能的sendfile
對于帶有DMA收集拷貝功能的sendfile系統(tǒng)調(diào)用,還可以再減少一次內(nèi)核緩沖區(qū)之間的拷貝。具體流程如下:
- sendfile系統(tǒng)調(diào)用利用DMA引擎將文件數(shù)據(jù)拷貝到內(nèi)核緩沖區(qū),之后,將帶有文件位置和長度信息的緩沖區(qū)描述符添加到內(nèi)核socket緩沖區(qū)中
- DMA引擎會將數(shù)據(jù)直接從內(nèi)核緩沖區(qū)拷貝到協(xié)議引擎中
這個過程數(shù)據(jù)經(jīng)歷的拷貝操作如下:
硬盤—>內(nèi)核緩沖區(qū)—>協(xié)議引擎
參考資料
1、Linux 中直接 I/O 機(jī)制的介紹
2、Linux 中的零拷貝技術(shù),第 1 部分
3、Linux 中的零拷貝技術(shù),第 2 部分