1. page cache
linux操做系統默認狀況下寫都是有寫緩存的,可使用direct IO方式繞過操做系統的寫緩存。當你寫一串數據時,系統會開闢一塊內存區域緩存這些數據,這塊區域就是咱們常說的page cache(操做系統的頁緩存)。查看系統內存經常使用的命令有:vmstat、free、top等。
可使用 cat /proc/meminfo 查看詳細的內存使用狀況
其中的Cached爲140M左右(page cache)。注意其中有一個Dirty: 24KB,表示當前有24KB的數據緩存在page cache,這些數據等待後臺線程刷入磁盤。隨着寫入數據增長,這個值也會增長。
2. writeback
有了page cache就有了writeback寫方式。一個寫IO會先寫入page cache,而後等待後臺pdflush把page cache中髒數據刷入磁盤。若是在刷入磁盤以前系統斷電,則page cache的數據丟失。因此對一些可靠性要求高的場景都會把這個寫緩存禁掉。writeback寫方式是linux操做系統提供的一種很是通用寫模式。writeback提供了較好的吞吐量,有了緩存也縮短了IO響應時間。但它也有缺點:(1)斷電可能丟數據(數據安全性)(2)對於像數據庫這樣自緩存的系統來講,多了一層IO緩存開銷。由於數據庫已經在應用層作了一層緩存。因此對於這樣的應用能夠用direct io方式,減小用戶空間和page cache之間數據複製開銷。(3)若是page cache過大,那麼就會緩存太多的數據,當須要統一刷入磁盤的時候就會出現一個IO峯值和瓶頸,在這其間對用戶的IO訪問出現明顯影響。若是想削平這個峯值能夠把page cache容量設置小一點,讓pdflush一段時間內較爲平均的刷新dirty數據。
3. pdflush
pdflush是linux系統後臺運行的一個線程,這個進程負責把page cahce中的dirty狀態的數據按期的輸入磁盤。一個系統中會運行不少這個pdflush。cat /proc/sys/vm/nr_pdflush_threads查看當前系統運行pdflush數量。當一段時間(通常是1s)沒有任何的pdflush處於工做狀態,系統會remove一個pdflush線程。pdflush最大和最小的數量是有配置的,但這些配置通常不多修改。
4. 幾個重要的IO寫相關參數
4.1 dirty_writeback_centisecs
cat /proc/sys/vm/dirty_writeback_centisecs查看這個值,默認通常是500(單位是1/100秒)。這個參數表示5s的時間pdflush就會被喚起去刷新髒數據。沒有官方文檔說明減小這個值就會有更多的pdflush參與刷數據。好比2.6或者更早的內核,linux中mm/page-writeback.c的源碼中有這樣一段
描述「若是pdflush刷新髒數據的時間超過了這個配置時間,則完成刷新後pdflush會sleep 1s「。這種擁塞的保護機制描述只是寫在源碼裏,並無寫入官方文檔或者造成規範,因此也就意味着這種機制在不一樣的版本可能有不一樣的表現。
因此修改dirty_writeback_centisecs並不必定能給你帶來多少性能的提高,相反有可能出現你意想不到的問題。通常建議用戶使用默認值。
4.2 dirty_expire_centisecs
cat /proc/sys/vm/dirty_expire_centicecs查看這個值,默認是3000(單位是1/100秒)。這個值表示page cache中的數據多久以後被標記爲髒數據。只有標記爲髒的數據在下一個週期到來時pdflush纔會刷入到磁盤,這樣就意味着用戶寫的數據在30秒以後纔有可能被刷入磁盤,在這期間斷電都是會丟數據的。若是想pdfflush刷新頻率大寫能夠減少這個值,好比:echo 1000 >> /proc/sys/vm/dirty_expire_centicecs 設置爲10s一個刷新週期。
4.3 dirty_backgroud_ratio
cat /proc/sys/vm/dirty_backgroud_ratio查看這個值,默認是10(單位是百分比,不一樣的內核版本可能有不一樣的默認值)。不少的描述文檔中描述這個值表示最多緩存髒數據的空間佔總內存的百分比。其實否則,查看源碼的描述,它的真實意義是佔(MemFree + Cached - Mapped)的百分比。達到這個上限後會喚醒pdflush把這些髒數據刷新到磁盤,在把髒數據輸入磁盤以前全部寫IO會被阻塞。因此若是這個值設的過大,則會週期的出現一個寫IO峯值,並且這個峯值持續比較長時間,在這段時間內用戶的寫IO會被阻塞。對於一些業務場景須要把這個值設置的小寫,把峯值寫IO平分爲屢次小的寫IO。例如:echo 5 >> cat /proc/sys/vm/dirty_backgroud_ratio 把百分比下降到5%。
4.4 dirty_ratio
cat /proc/sys/vm/dirty_ratio查看這個值,默認是20(單位是百分比,不一樣的內核版本可能有不一樣的默認值)。表示當髒數據佔用總內存的百分比超過20%的時候,內核會把全部的寫操做阻塞掉,等待pdflush把這些髒數據刷入到磁盤後才能恢復正常的IO寫。要注意的是當這個事件發生時,會阻塞掉全部寫操做。這樣會產生一個很大的問題,一個長時間大IO會搶佔更多的IO寫資源,可能把其它的小IO餓死。由於大IO產生的髒數據較多,很快達到這個閥值,此時就會系統會阻塞掉全部的寫IO,從而小寫IO沒法進行寫操做。