磁碟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; #配置檔案最大後表示大於大小非同步iosyntax: directio_alignment size; 讀取檔案緩衝區
普通io:當程式發起乙個系統呼叫去讀乙個檔案時,程式這時會被阻塞住等待讀取到檔案再次執行,這是先到核心空間發起乙個read請求,開始去讀磁碟資料,讀到快取記憶體(記憶體)裡,這時喚醒程序繼續執行;寫的時候是直接寫到快取記憶體(記憶體)裡,之後自動同步
非同步io: 當使用者發起乙個讀操作時,程式不會被阻塞在**,可以去處理其他請求
nginx指令啟用非同步io
syntax: aio on | off | threads[=pool]; # 最後這個是執行緒池;調應的非同步io執行緒池的定義,預設未編譯--with-threadssyntax: aio_write on | off; #設定寫時啟用aio;預設是關閉的;
執行緒池:worker程序在處理時,有一些請求可能會發生一些阻塞,這是我們就不能接受worker程序的阻塞,而是在worker程序裡定義一些執行緒池,由執行緒池裡的執行緒處理這些可能發生系統阻塞的工作;為什麼會出現這樣的場景呢:因為nginx在做靜態資源伺服器的時候,處理了太多的檔案,因為處理檔案太多,會導致檔案快取的inode失效,因為記憶體不夠大而導致的,一些操作大部分情況下會命中記憶體中快取的。
定義執行緒池
syntax: thread_pool name threads=number [max_queue=number]; #在靜態服務的情況下使用執行緒池非同步io中快取default: thread_pool default threads=32 max_queue=65536; # max_queue是定義佇列最大長度;threads=32 執行緒池裡執行緒個數
context: main
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->logsyslog協議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
sendfile 零拷貝技術
應用程式普通呼叫:應用程式先發起乙個讀請求,從磁碟讀到核心再從核心讀到應用程式快取裡,然後程式再把快取裡的資料寫到核心的socket緩衝再進行傳送
sendfile技術:程式程式只發起乙個sendfile 的呼叫,告訴核心我要把磁碟資料從**開始讀讀取多少位元組,然後把讀到的資料傳送到那個socket套接字上
sendfile 、直接io、非同步io同時啟用時
直接io會禁用sendfile技術
location /video/gzip_static 模組: ngx_http_gzip_static_module,通過--with-http_gzip_static_module啟用該模組當檔案大小超過8m時,啟用aio與directio
syntax: gzip_static on | off | always; #不管客戶端是否支援壓縮我都把壓縮檔案發給客戶端always ;on是會判斷客戶端是否會支援壓縮
default: gzip_static off; context: http, server, locationgunzip : 模組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...