sendfile原理,實現文件傳輸性能的提升

原文地址:http://calmness.iteye.com/blog/378463

在apache,nginx,lighttpd等web服務器當中,都有一項sendfile相關的配置,在一些網上的資料都有談到sendfile會提升文件傳輸性能,那sendfile到底是什麼呢?它的原理又是如何呢?

在傳統的文件傳輸裏面(read/write方式),在實現上其實是比較複雜的,需要經過多次上下文的切換,我們看一下如下兩行代碼:

Java代碼  收藏代碼
  1. read(file, tmp_buf, len);      

  2.       write(socket, tmp_buf, len);      


       以上兩行代碼是傳統的read/write方式進行文件到socket的傳輸。

當需要對一個文件進行傳輸的時候,其具體流程細節如下:
1、調用read函數,文件數據被copy到內核緩衝區
2、read函數返回,文件數據從內核緩衝區copy到用戶緩衝區
3、write函數調用,將文件數據從用戶緩衝區copy到內核與socket相關的緩衝區。
4、數據從socket緩衝區copy到相關協議引擎。

以上細節是傳統read/write方式進行網絡文件傳輸的方式,我們可以看到,在這個過程當中,文件數據實際上是經過了四次copy操作:

硬盤—>內核buf—>用戶buf—>socket相關緩衝區—>協議引擎

而sendfile系統調用則提供了一種減少以上多次copy,提升文件傳輸性能的方法。Sendfile系統調用是在2.1版本內核時引進的:
Java代碼  收藏代碼
  1. sendfile(socket, file, len);  


運行流程如下:
1、sendfile系統調用,文件數據被copy至內核緩衝區
2、再從內核緩衝區copy至內核中socket相關的緩衝區
3、最後再socket相關的緩衝區copy到協議引擎

相較傳統read/write方式,2.1版本內核引進的sendfile已經減少了內核緩衝區到user緩衝區,再由user緩衝區到socket相關緩衝區的文件copy,而在內核版本2.4之後,文件描述符結果被改變,sendfile實現了更簡單的方式,系統調用方式仍然一樣,細節與2.1版本的不同之處在於,當文件數據被複制到內核緩衝區時,不再將所有數據copy到socket相關的緩衝區,而是僅僅將記錄數據位置和長度相關的數據保存到socket相關的緩存,而實際數據將由DMA模塊直接發送到協議引擎,再次減少了一次copy操作。

以上描述雖然簡單,但實際情況會更加複雜,本文只希望以簡單的方式大致上講解sendfile的原理,並不奢望通過本文能夠闡述出所有的細節,我也沒這水平,希望此文對各位朋友有所幫助。

參考自:http://www.linuxjournal.com/article/6345


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章