在我們使用 squid 的環境裡,常常遇到一個瓶頸,就是面對高 I/O 的環境底下,整個系統的效能表現會變的特別差,如果看系統的 CPU 線圖會如下(下圖爲 cacti 畫的日圖):
可以看到在深夜時段(也就是大量 request 圖片)時 I/O wait 整個就咬死 CPU,因爲在大量的 request 進來時 squid 會有同時的磁碟寫入跟讀取,不過我們的系統是 IBM 的 blade server 配有 ServerRAID 8k 的卡,上面有 256MB 的 Read/Write Cache/Buffer,所以總覺的讀寫性能應該可以不錯才對,可是偏偏就是在晚上很容易拖慢系統的速度。後來找到了幾個可能的參數調一調之後,現在系統的線圖如下(此爲周圖):
可以看到在中間過後(也就是修改後),整體系統的 I/O waiting 就降低了,這中間的修改其實是動了下列的 Linux kernel 參數:
主要都是在 /etc/sysctl.conf
這個檔案 新增/修改 以下參數 (影響的資料夾在 /proc/sys/vm/
)
vm.dirty_background_ratio = 1
這個參數主要是降低 Linux 寫檔案(dirty page)的 buffer 大小,如果是寫入的量很大的系統建議降低此值,因爲這樣會讓寫入更連續而且一致,而不會分批次每次都寫入大量的資料,Linux 原本預設的值太大了,這個值的算法是MemFree + Cached - Mapped
(指令cat /proc/meminfo
可以看到) 假設我們算出來系統有 3G 而這個值爲 10 時表示 10% 則相當於超過 300MB 的 dirty page 才開始回寫硬碟,我猜是因爲這樣讓 Linux 的 I/O 變的很慢,因爲這個值也大於 RAID 卡的記憶體了,而且邊寫入又一直有 dirty page 一直進來,所以建議把這個值降低,我是直接設定成 1 也就是 1% 約 30M 就開始寫;相對於百分比,Linux 後來的 2.6.29 kernel 加入了vm.dirty_background_bytes
是以 bytes 來計算vm.dirty_ratio = 2
相對於vm.dirty_background_ratioad
是所謂的”背景”寫入,實際上是透過 Linux 裏面的一隻叫pdflush kernel thread
來回寫,vm.dirty_ratio
是如果 dirty page 真的超過多少就強制回寫,而不是透過背景慢慢回寫,所以vm.dirty_ratio
更硬性,而vm.dirty_background_ratio
則相對較於軟性,也因爲這個特性當然vm.dirty_background_ratio
是不會超過vm.dirty_ratio
的,預設上(或者設定錯誤時)vm.dirty_background_ratio
=vm.dirty_ratio
/2 ,所以如果vm.dirty_background_ratio = 1
則我們可以設定vm.dirty_ratio = 2
,同樣的 2.6.29 之後也有一個vm.dirty_bytes
vm.dirty_writeback_centisecs = 100
單位是百分之一秒,這個就是多久要觸發回寫,預設也蠻大的好像有 500,也就是 5 秒才寫一次,建議在高寫入的系統設定短一點,我設定成 100 也就是每秒寫入一次(反正是先寫回 raid 卡的 cache),這樣以來可以讓寫入更均勻。vm.dirty_expire_centisecs = 1000
單位也是百分之一秒,這個是表示 dirty page 過了多久之後下次pdflush kernel thread
醒來時就會被寫回硬碟,預設是 3000 也就是 30 秒,一樣可以設低一點讓寫入均勻化,不過太低會一直寫,也不宜太低。
參考資料: