背景
io性能調優之page cache
什么是緩存
緩存,其實就是一塊內存,能幫硬盤HOLD住大量的請求,有效地緩解高速的CPU和低速的硬盤之間的矛盾
磁盤緩存write_back模式流程
用戶輸入的數據->page cache -> 磁盤(如下圖 Buffered IO)
磁盤緩存臟數據
- 如何定義:cache中的數據與磁盤中的數據不一致,即為臟數據
- 如何產生:頻繁的覆蓋寫操作,例如
- T1時刻 用戶寫入1 -> cache 中存1 -> 磁盤中存1
- T2時刻 用戶寫入2 -> cache 中存2 (此時hold 一直未繼續落盤,稱此刻cache中的2 與 磁盤中的1存在數據不一致,cache中的2為臟數據)
- 如何處理cache中的臟數據
- 內核有一套機制,可以使cache中的數據落盤
- 機制大致邏輯是從臟數據在cache內存中的空間大小,存在時間大小,設置閾值,達到一定的閾值后,將臟頁flush到磁盤
影響臟數據在cache緩存flush操作閾值的參數
按空間大小調整
- vm.dirty_background_ratio = 10 # 內存可以填充臟數據的百分比,例如內存32G,該參數設為10,即臟數據最大為3.2G,超過3.2G就啟動flush落盤清理臟數據,此時臟數據依然可以寫入內存。
- vm.dirty_background_bytes = 0 # 與1相同的作用,1中設置不為0時,該參數設置失效
- vm.dirty_ratio = 30 # 是可以用臟數據填充的絕對最大系統內存量,當系統到達此點時,必須將所有臟數據提交到磁盤,同時所有新的
I/O
塊都會被阻塞,不允許寫到內存中,直到臟數據被寫入磁盤。這通常是長I/O
卡頓的原因,但這也是保證內存中不會存在過量臟數據的保護機制 - vm.dirty_bytes = 0 # 與3相同的作用,3中設置不為0時,該參數設置失效
代碼源碼 (其中,thresh/bg_thresh的單位均為page)

static void domain_dirty_limits(struct dirty_throttle_control *dtc) { … unsigned long bytes = vm_dirty_bytes; unsigned long bg_bytes = dirty_background_bytes; if (bytes) thresh = DIV_ROUND_UP(bytes, PAGE_SIZE); else thresh = (ratio * available_memory) / PAGE_SIZE; if (bg_bytes) bg_thresh = DIV_ROUND_UP(bg_bytes, PAGE_SIZE); else bg_thresh = (bg_ratio * available_memory) / PAGE_SIZE; if (bg_thresh >= thresh) bg_thresh = thresh / 2; tsk = current; if (tsk->flags & PF_LESS_THROTTLE || rt_task(tsk)) { bg_thresh += bg_thresh / 4 + global_wb_domain.dirty_limit / 32; thresh += thresh / 4 + global_wb_domain.dirty_limit / 32; } … }
按時間使用調整
- vm.dirty_expire_centisecs = 3000 # 默認值30 * 100,即3000毫秒,是臟數據可持續的最長時間,超過該時間臟數據必須完成同步
- vm.dirty_writeback_centisecs = 500 # 默認500ms,如果inode被標記為dirty,就會確保500ms后喚醒wb進行后台回寫,減小該值可加快元數據的同步
總結
- 上述參數改小,降低磁盤IO性能,但對系統流暢程度有利,不會出現卡頓情況
- 上述參數改大,有利於提升磁盤IO性能
參考