磁盤IO優化的幾個方面
優化讀取
適用於大文件的直接IO
當磁盤文件超過size大小之后,使用directIO功能,避免Buffered IO模式下磁盤頁緩存中的拷貝消耗
Syntax: directio size | off; #配置文件最大后表示大於大小 Default: directio off; Context: http, server, location Syntax: directio_alignment size; 讀取文件緩沖區 Default: directio_alignment 512; Context: http, server, location
異步IO
普通IO:當程序發起一個系統調用去讀一個文件時,程序這時會被阻塞住等待讀取到文件再次執行,這是先到內核空間發起一個read請求,開始去讀磁盤數據,讀到高速緩存(內存)里,這時喚醒進程繼續執行;寫的時候是直接寫到高速緩存(內存)里,之后自動同步
異步IO: 當用戶發起一個讀操作時,程序不會被阻塞在哪里,可以去處理其他請求
nginx指令啟用異步IO
Syntax: aio on | off | threads[=pool]; # 最后這個是線程池;調應的 Default: aio off; Context: http, server, location Syntax: aio_write on | off; #設置寫時啟用AIO;默認是關閉的; Default: aio_write off; Context: http, server, location
異步IO線程池的定義,默認未編譯--with-threads
線程池:worker進程在處理時,有一些請求可能會發生一些阻塞,這是我們就不能接受worker進程的阻塞,而是在worker進程里定義一些線程池,由線程池里的線程處理這些可能發生系統阻塞的工作;為什么會出現這樣的場景呢:因為nginx在做靜態資源服務器的時候,處理了太多的文件,因為處理文件太多,會導致文件緩存的inode失效,因為內存不夠大而導致的,一些操作大部分情況下會命中內存中緩存的。
定義線程池
Syntax: thread_pool name threads=number [max_queue=number]; #在靜態服務的情況下使用線程池 Default: thread_pool default threads=32 max_queue=65536; # max_queue是定義隊列最大長度;threads=32 線程池里線程個數 Context: main
異步IO中緩存
Syntax: output_buffers number size; Default: output_buffers 2 32k; Context: http, server, location
empty_gif 模塊默認是編譯進nginx中的
ngx_http_empty_gif_module
功能:從前端用戶做用戶行為分析時,由於跨域等請求,前端打點的上報數據是get請求,且考慮到瀏覽器接卸DOM樹的性能消耗,所以請求透明圖片消耗最小,而1*1的gift圖片體積最小(僅43字節),故通常請求gif圖片,並在請求中把用戶行為信息上報服務器;Nginx可以在access日志中獲取到請求參數,進而統計用戶行為,但若在磁盤中讀取1x1的文件有磁盤IO消耗,empty_gif模塊將圖片放在內存中,加速了處理速度
Syntax: empty_gif; Default: — Context: location
記錄日志時啟用壓縮功能
Syntax: access_log path [format [buffer=size] [gzip[=level]] [flush=time][if=condition]]; #[buffer=緩存大小][gzip[=壓縮比例可選1-9,數字越大壓縮的越小,話的時間越多]] [flush=最長刷新時間] Default: access_log logs/access.log combined; Context: http, server, location, if in location, limit_except
error.log 日志內容輸出到內存中
場景:開發環境下定位,若需要打開debug級別日志,但大量的debug日志引發性能問題不能容忍,可以將日志輸出到內存中
配置語法
error_log memory:32m debug;
查看中日志方法
gdb-p[worker 進程 ID ] -ex "source nginx.gdb" --batch nginx.gdb腳本內容
set $log = ngx_cycle->log while $log->writer != ngx_log_memory_writer set $log = $log->next end set $buf = (ngx_log_memory_buf_t *) $log->wdata dump binary memory debug_log.txt $buf->start $buf->end
syslog協議

應用程序普通調用:應用程序先發起一個讀請求,從磁盤讀到內核再從內核讀到應用程序緩存里,然后程序再把緩存里的數據寫到內核的socket緩沖再進行發送
sendfile技術:程序程序只發起一個sendfile 的調用,告訴內核我要把磁盤數據從哪里開始讀讀取多少字節,然后把讀到的數據發送到那個socket套接字上
直接IO會禁用sendfile技術
location /video/ { sendfile on; aio on; directio 8m; } 當文件大小超過8M時,啟用AIO與directio
Syntax: gzip_static on | off | always; #不管客戶端是否支持壓縮我都把壓縮文件發給客戶端always ;on是會判斷客戶端是否會支持壓縮
Default: gzip_static off; Context: http, server, location
gunzip : 模塊ngx_http_gunzip_module,通過--with-http_gunzip_module啟用該模塊
功能:當客戶端不支持gzip壓縮時,且磁盤上僅有壓縮文件,則實時解壓縮並將其發送給客戶端
Syntax: gunzip on | off; Default: gunzip off; Context: http, server, location Syntax: gunzip_buffers number size; #打開內存緩存區 Default: gunzip_buffers 32 4k|16 8k; Context: http, server, location
wget https://github.com/gperftools/gperftools/releases/download/gperftools-2.7/gperftools-2.7.tar.gz [root@python ]# tar xf gperftools-2.7.tar.gz [root@python ]# cd gperftools-2.7/ [root@python gperftools-2.7]# ./configure [root@python gperftools-2.7]# make && make install 查看生成庫文件路徑/usr/local/lib/ ll /usr/local/lib/libtcmalloc.so