nginx 的磁碟IO優化

2022-06-27 04:51:10 字數 4494 閱讀 4884

磁碟io優化的幾個方面

優化讀取

sendfile 零拷貝、記憶體盤、ssd盤

減少寫入

aio增大error_log級別的日誌

關閉access_log 

壓縮access_log

是否啟用proxy buffering

syslog替代本地io

執行緒池 thread pool

適用於大檔案的直接io

當磁碟檔案超過size大小之後,使用directio功能,避免buffered io模式下磁碟頁快取中的拷貝消耗

syntax: directio size | off;  #配置檔案最大後表示大於大小

syntax: directio_alignment size; 讀取檔案緩衝區

非同步io

普通io:當程式發起乙個系統呼叫去讀乙個檔案時,程式這時會被阻塞住等待讀取到檔案再次執行,這是先到核心空間發起乙個read請求,開始去讀磁碟資料,讀到快取記憶體(記憶體)裡,這時喚醒程序繼續執行;寫的時候是直接寫到快取記憶體(記憶體)裡,之後自動同步

非同步io: 當使用者發起乙個讀操作時,程式不會被阻塞在**,可以去處理其他請求

nginx指令啟用非同步io

syntax: aio on | off | threads[=pool];  # 最後這個是執行緒池;調應的

syntax: aio_write on | off; #設定寫時啟用aio;預設是關閉的;

非同步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中快取

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=最長重新整理時間]

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協議

sendfile 零拷貝技術

應用程式普通呼叫:應用程式先發起乙個讀請求,從磁碟讀到核心再從核心讀到應用程式快取裡,然後程式再把快取裡的資料寫到核心的socket緩衝再進行傳送

sendfile技術:程式程式只發起乙個sendfile 的呼叫,告訴核心我要把磁碟資料從**開始讀讀取多少位元組,然後把讀到的資料傳送到那個socket套接字上

sendfile 、直接io、非同步io同時啟用時

直接io會禁用sendfile技術

location /video/ 

當檔案大小超過8m時,啟用aio與directio

gzip_static 模組: ngx_http_gzip_static_module,通過--with-http_gzip_static_module啟用該模組

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_buffers number size; #開啟記憶體快取區

tcmalloc 記憶體分配器

更快的記憶體分配器:併發能力強於glibc;併發執行緒數越多,效能越好 ;減少記憶體碎片;擅長管理小塊記憶體。這是谷歌提供的第三方模組介紹:

安裝此系統模組

wget 

[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

mysql 磁碟讀寫的I O優化

在 mysql 5.1.x 版本中曾使用引數innodb file io threads,指負責處理資料頁上讀寫io請求的後台執行緒數量。在 mysql 5.5.x 中拆成2個引數 innodb read io threads,innodb write io threads。該引數值之和 2 cpu...

常見的磁碟I O和網路I O優化技巧

應用程式通過訪問磁碟來讀取資料,而磁碟i o 通常都是很耗時間的,所以一般我們來判斷i o是否有瓶頸的時候,就需要一些引數指標來參考。通常提公升i o效能的方法有 磁碟數 每塊磁碟的iops 磁碟的吞吐量 raid因子 磁碟讀寫的吞吐量 iops raid 策略 以及說明 磁碟陣列 說明 raid ...

Mysql的磁碟IO的讀過高的優化

最近幾個站點出現負載過高,磁碟io過高,通過iotop命令檢視,發現程序為mysqld的讀資料操作很高。基本上在200mb s。已經到達了100 了。在網上找了好幾天都是說binglog提交,set global sync binlog 500 當每進行500次事務提交之後,mysql將進行一次fs...