改了 vm.dirty_expire_centisecs 仍卡,因未同步调整 vm.dirty_writeback_centisecs;后者需 ≤ 前者(建议设为一半),否则过期脏页无法及时回写。

为什么改了 vm.dirty_expire_centisecs 还是卡?
这个参数控制脏页“过期时间”,单位是厘秒(centiseconds),默认 3000(即 30 秒)。但单纯调小它,比如设成 500(5 秒),并不一定减少卡顿——因为内核真正触发回写,还得看 vm.dirty_writeback_centisecs 是否及时唤醒回写线程。
常见错误是只调 dirty_expire_centisecs,却忽略 dirty_writeback_centisecs 的配合。后者默认 500(5 秒),表示内核每 5 秒唤醒一次 pdflush(或现代内核的 writeback 线程)去扫描过期脏页。如果它太长,即使页已过期,也得等下一轮扫描才开始写,造成延迟堆积。
-
vm.dirty_writeback_centisecs应 ≤vm.dirty_expire_centisecs,否则过期页可能滞留多个周期 - 生产环境建议设为
dirty_expire_centisecs / 2左右,例如 expire=1000,则 writeback=500 - 值过小(如 writeback=100)会导致频繁唤醒线程,增加调度开销,尤其在高 I/O 负载下反而加剧抖动
vm.dirty_ratio 和 vm.dirty_background_ratio 怎么配合 dirty 回写节奏?
这两个参数决定内存中脏页占比阈值,直接影响是否触发同步/异步回写,和上面两个时间参数共同构成“水位 + 时间”双控机制。
典型卡顿场景:应用突发写入大量数据,dirty_background_ratio(默认 10)很快被突破,内核启动后台回写;但如果磁盘慢,脏页持续累积,逼近 vm.dirty_ratio(默认 20),此时所有新写入线程会被阻塞,直到脏页降到 dirty_ratio 以下——这就是“卡住”的根源。
- 若磁盘吞吐能力弱(如机械盘、高延迟云盘),适当降低
vm.dirty_background_ratio(如设为 5),让后台回写更早介入 -
vm.dirty_ratio不建议低于 10,否则容易因瞬时写入波动就触发阻塞;也不建议高于 30,会显著拉高 OOM 风险 - 注意:这些 ratio 是相对于
vm.lowmem_reserve_ratio之外的可用内存计算的,不是总内存百分比
如何验证当前 dirty 回写是否真的成为瓶颈?
别猜,用工具看实际行为。关键指标不是“有没有脏页”,而是“脏页是否堆积 + 回写是否滞后”。
- 查实时脏页状态:
grep -i dirty /proc/meminfo,重点关注Dirty:和Writeback:行。如果Writeback长时间 > 0 且Dirty持续上升,说明回写跟不上 - 看内核日志是否有
writeback: balance_dirty_pages相关 trace(需开启echo 1 > /proc/sys/vm/block_dump或用perf),确认是否频繁进入阻塞路径 - 用
iostat -x 1观察%util和await:若await突增且Dirty同步上涨,基本可定位为 dirty 回写压垮磁盘
SSD 和 NVMe 场景下要不要调?
要,但方向相反。SSD/NVMe 的随机写延迟低、并行度高,传统“保守延后写”的策略反而浪费性能。
默认的 30 秒过期时间对 SSD 来说太长,容易导致脏页批量冲刷,引发短时 I/O 尖峰。而 SSD 更适合细粒度、高频次的轻量回写。
- 可将
vm.dirty_expire_centisecs降至 500–1000(5–10 秒),vm.dirty_writeback_centisecs设为 200–500(2–5 秒) -
vm.dirty_background_ratio可适度提高到 15,避免过早触发回写干扰前台 IO;但vm.dirty_ratio仍建议维持 20–25,防止内存耗尽 - 注意:某些 NVMe 驱动或文件系统(如 XFS)对 writeback 线程并发数敏感,若调得太激进,可能触发
writeback: bdi-X: writeback timeout类似错误
最易被忽略的是:这些参数在容器或 cgroup v2 环境下可能被覆盖,/sys/fs/cgroup/ 下的 memory.pressure 和 io.pressure 才是更直接的信号源。










