nginx AIO機制與sendfile機制

nginx AIO機制與sendfile機制

從0.8.11版本開始, nginx 開始支持Linux native aio,如何在nginx里配置使用這套機制是本文介紹的重點。在下面的示例配置中,幾個重要相關選項的具體含義如下: aio:

Syntax: aio on | off | sendfile
Default: off

在linux下aio可以設置為on或off(在freebsd還可以設置為sendfile),但需要2.6.22及以后版本的內核,原因在前面文章已經提到過,nginx使用的eventfd有這個 要求 。

directio:

Syntax: directio size | off
Default: off

directio選項可以設置為off或一個大小值,表示當文件大小大于等于這個值時啟用directio。

sendfile:

Syntax: sendfile on | off
Default: off

是否啟用sendfile()。

[root@www nginx-1.2.0]# uname -a
Linux www.t1.com 2.6.38.8 #2 SMP Wed Nov 2 07:52:53 CST 2011 x86_64 x86_64 x86_64 GNU/Linux
[root@www nginx-1.2.0]# cat /etc/issue
CentOS Linux release 6.0 (Final)
Kernel \r on an \m

[root@www nginx-1.2.0]# ./configure --with-file-aio
[root@www nginx-1.2.0]# make
[root@www nginx-1.2.0]# make install
[root@www nginx-1.2.0]# cat /usr/local/nginx/conf/nginx.conf
...
http {
...
server {
...
location / {
aio on;
directio 512k;
sendfile on;
output_buffers 1 128k;
...

要使aio生效需把directio設置為打開狀況,并且如果aio生效,那么將自動不使用sendfile(),這在linux下這是顯然的,要么利用aio讀到緩存區,要么利用sendfile()直接發送出去,兩者不可兼用,而對于freebsd系統下aio和sendfile并用的情況,我并不了解,所以也就不妄加評論;

可以看到directio是針對每個請求的文件大小而決定是否開啟directio的,因此對于上面的整個示例配置,也就會針對每個請求的不同而不同: 如果某處請求的文件大于等于512k,那么將啟用directio,從而aio生效,進而sendfile不生效; 如果某處請求的文件小于512k,那么將禁用directio,從而aio也就不生效,轉而使用sendfile(),即sendfile生效;

這種設計貌似剛好把linux下aio和sendfile兩種機制的優點很好的結合起來使用。對于大文件采用aio,節省cpu,而對于小文件,采用sendfile,減少拷貝;并且對于大文件aio采用directio,避免擠占文件系統緩存,讓文件系統緩存更多的小文件。 從理論上來看,這種配置比較適合系統內存有限、小文件請求比較多、間隔有幾個大文件請求的Web環境;如果內存足夠大,那么應該充分利用文件系統緩存,而directio使得aio無法使用緩存是衡量最終是否需要采用aio的一個需要仔細考慮的因素;網上有人總結說nginx+aio很好,也有人說其很差,其實根據特定的系統環境和應用場景來做配置調節,才能達到性能的最優,nginx提供的 AIO 只是一套工具,沒有固定的好與差之分,就看你能否恰當的用好它,但據nginx官網論壇來看,在linux系統的大部分場景下,目前因使用aio功能附加的限制而帶來的實際效果估計并不太理想:

nginx supports file AIO only in 0.8.11+, but the file AIO is functional
on FreeBSD only. On Linux AIO is supported by nginx only on kerenl
2.6.22+ (although, CentOS 5.5 has backported the required AIO features).
Anyway, on Linux AIO works only if file offset and size are aligned
to a disk block size (usually 512 bytes) and this data can not be cached
in OS VM cache (Linux AIO requires DIRECTIO that bypass OS VM cache).
I believe a cause of so strange AIO implementaion is that AIO in Linux
was developed mainly for databases by Oracle and IBM.

示例:

location /video/ {
sendfile on;
sendfile_max_chunk 256k; 
aio threads;
directio 512k;
output_buffers 1 128k;
}

啟用aio時會自動啟用directio,小于directio定義的大小的文件則采用sendfile進行發送,超過或等于directio定義的大小的文件,將采用aio線程池進行發送,也就是說aio和directio適合大文件下載.因為大文件不適合進入操作系統的buffers/cache,這樣會浪費內存,而且Linux AIO(異步磁盤IO)也要求使用directio的形式.

sendfilemaxchunk可以減少阻塞調用sendfile()所花費的最長時間.因為Nginx不會嘗試一次將整個文件發送出去,而是每次發送大小為256KB的塊數據.

注意,Nginx從1.7.11開始為AIO引入了線程池支持,能夠使用多線程讀取和發送文件,以免工人進程被阻塞.要啟用多線程支持,configure時需要顯式加入–with-threads選項.

sendfile機制:

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

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

read(file, tmp_buf, len);      
       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代碼 收藏代碼

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操作。

原創文章,作者:YOUNG,如若轉載,請注明出處:http://www.www58058.com/54790

(19)
YOUNGYOUNG
上一篇 2016-10-26 22:28
下一篇 2016-10-27 09:41

相關推薦

  • 8-1作業

    1、創建testuser uid 1234,主組:bin,輔助組:root,ftp,shell:/bin/csh home:/testdir/testuser [root@localhost ~]# useradd -u 1234 -g bin -G root,ftp …

    Linux干貨 2016-08-03
  • 馬哥教育網絡班20期+第二周課程練習

    1、Linux上的文件管理類命令都有哪些,其常用的使用方法及其相關示例演示。 2、bash的工作特性之命令執行狀態返回值和命令行展開所涉及的內容及其示例演示。 3、請使用命令行展開功能來完成以下練習:    (1)、創建/tmp目錄下的:a_c, a_d, b_c, b_d   …

    Linux干貨 2016-06-23
  • Linux udev-ASM(基于oracle5.8)

    之前有客戶有在Linux下使用udev來做ASM,操作系統版本為oracle5.8,實際跟rhel5.8差不多,當時只是做了簡單記錄,現在整理下來,與大家一起分享。 1)需求信息 磁盤分區操作 –省略– 分區后,使用parted讓磁盤生效 需求: 將/dev/sdc1 <–>/dev/asm-disk1 將/d…

    Linux干貨 2016-07-29
  • N26第三周博客作業

    1、列出當前系統上所有已經登錄的用戶的用戶名,注意:同一個用戶登錄多次,則只顯示一次即可。    who | cut -d' ' -f1 | sort -u 2、取出最后登錄到當前系統的用戶的相關信息。    last | head -1   3、取出當前系統上被用戶當作其默認s…

    Linux干貨 2017-02-03
  • linux系統上的特殊權限SUID,SGID,STICKY

    特殊權限:SUID SGID STICKY     linux的安全上下文:     1.進程以用戶的身份運行,進程是發起此用戶的代理,因此以此用戶的身份和權限完成所有的操作。     2.權限匹配模型:     1)判斷進程的屬主,是否以被訪問的文件屬主。如果是,則應用屬主權限…

    Linux干貨 2016-08-05
  • 虛擬機的安裝

    虛擬機的安裝步驟: 1、打開VMware點擊創建新的虛擬機 2、選擇典型安裝方式點擊下一步 3、選擇稍后安裝操作系統點擊下一步 4、客戶機操作系統選擇Linux,版本選擇Centos 64位 5、設定虛擬機的名稱及存放路徑 6、設定磁盤的容量,選中將虛擬磁盤存儲為單個文件 7、對虛擬設備進行設置 8、CD/DVD此項選中使用ISO映像文件并選擇映像所在路徑 …

    2018-03-27
欧美性久久久久