Page Cache的落地问题
除非特別說明,否則本文提到的寫操作都是 buffer write/write back。
起因
前幾天討論到一個問題:Linux 下文件 close成功,會不會觸發 “刷盤”?
其實這個問題根本不用討論,查一下就知道。
man 2 close 的 NOTES 一節里有這么一段話:
A successful close does not guarantee that the data has been successfully saved to disk, as the kernel defers writes. It is not common for a filesystem to flush the buffers when the stream is closed. If you need to be sure that the data is physically stored use fsync(2). (It will depend on the disk hardware at this point.)
所以,一個文件的描述符被 close 成功,并不會觸發操作系統刷盤。
那么,問題來了,除了主動調用fsync(或相關函數)之外,Linux 什么時候會“刷盤”呢?
一次正常的寫流程
一次寫數據的典型流程(不考慮異常和其它特殊情況):
1、數據在用戶態的 buffer 中,調用 write 將數據傳給內核;
2、數據在 Page Cache 中,返回寫入的字節數(成功返回);
3、內核將數據刷新到磁盤。
第二步如果返回成功,說明數據已經到達操作系統的Page Cache,可以保證的是如果進程掛了,但是操作系統沒掛,數據不會丟失。
如果調用 fsync 將數據刷新到磁盤上,返回成功,說明數據已經刷新到硬件上了——我們一般認為如果 fsync 返回成功,則表示數據持久化成功。
Page Cache 的異步刷新
那么,如果不調用fsync或其它類似功能的接口,Page Cache 是什么時候刷回磁盤的呢?
簡單總結一下,有兩種情況:
1、臟頁太多。
2、臟頁太久。
這些都由 Linux 內核的后臺線程執行。相關的控制參數有:
說明: centy 中文意思是“百分之十”。
- dirty_writeback_centisecs 表示多久喚醒一次刷新臟頁的后臺線程。這里的500表示5秒喚醒一次。
- dirty_expire_centisecs 表示臟數據多久會被刷新到磁盤上。這里的3000表示 30秒。
- dirty_background_ratio 表示當臟頁占總內存的的百分比超過這個值時,后臺線程開始刷新臟頁。這個值如果設置得太小,可能不能很好地利用內存加速文件操作。如果設置得太大,則會周期性地出現一個寫 IO 的峰值。
- dirty_ratio 當臟頁占用的內存百分比超過此值時,內核會阻塞掉寫操作,并開始刷新臟頁。
- dirty_background_bytes、dirty_bytes 是和 dirty_background_ratio、dirty_ratio 表示同樣意義的不同單位的表示。兩者不會同時生效。
總結
觸發刷新臟頁的條件:
1、調用fsync等。
2、臟頁太多(相關參數:dirty_background_ratio與dirty_ratio)。
3、臟頁太久(相關參數:dirty_expire_centisecs)。
參考資料
- Linux Man Page
- Better Linux Disk Caching & Performance with vm.dirty_ratio & vm.dirty_background_ratio
作者:linjinhe
鏈接:https://www.jianshu.com/p/ed5900d31f1f
來源:簡書
著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。
轉載于:https://www.cnblogs.com/lushilin/p/9145523.html
總結
以上是生活随笔為你收集整理的Page Cache的落地问题的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 从操作系统层面描述线程的五种状态
- 下一篇: java中线程的6种状态