应优先调低vm.dirty_background_ratio并配合vm.dirty_writeback_centisecs等时间参数,而非单纯提高vm.dirty_ratio;ssd建议设为5/10,hdd为3/10,同时将vm.swappiness设为10以协同缓解内存压力。

直接调高 vm.dirty_ratio 并不能防止内存瞬时写满,反而可能加剧风险——它只是把阻塞点往后推,脏页仍在堆积。真正有效的做法是让后台回写节奏跟上写入速度,避免脏页在内存中“憋住”后集中爆发。
先确认是不是脏页在拖慢你
别凭感觉调参,先看真实指标:
- 运行
grep -i dirty /proc/meminfo,算出Dirty占MemAvailable的百分比。如果长期 >15%,尤其接近或超过vm.dirty_ratio,就是瓶颈 - 用
pidstat -d 1观察是否有大量进程状态为D(不可中断睡眠),同时iostat -x 1显示await持续 >5ms、%util接近 100%,基本锁定是刷盘跟不上 - 查
cat /proc/vmstat | grep pgpgout:如果每秒写出页数长期为 0 或剧烈跳变(比如 0→20000→0),说明后台线程没及时启动或节奏太慢
按存储类型设基础值
默认值(dirty_background_ratio=10、dirty_ratio=20)是为桌面设计的,服务器必须重设:
-
SSD/NVMe:延迟低、IOPS 高,适合早刷、勤刷 →
vm.dirty_background_ratio=5,vm.dirty_ratio=10 -
HDD:随机写差,宁可让应用稍等,也不让内核攒一堆再硬刷 →
vm.dirty_background_ratio=3,vm.dirty_ratio=10 -
混合负载(如 K8s 节点):折中起步 →
vm.dirty_background_ratio=10,vm.dirty_ratio=15
注意:dirty_background_ratio 必须严格小于 dirty_ratio,否则内核会静默忽略并恢复默认值。
配合时间类参数一起调
只改比例就像只踩油门不调档位,容易卡顿或抖动:
-
vm.dirty_writeback_centisecs=100(即 1 秒唤醒一次):加快后台线程调度频率,避免脏页积压;HDD 可放宽到 300(3 秒) -
vm.dirty_expire_centisecs=1500(即 15 秒):强制老化脏页尽快落地,防止某次写入后数据“赖”在内存太久;数据库类服务可缩到 1000(10 秒) - 若使用
_bytes类参数(如dirty_background_bytes),则对应_ratio参数会被忽略,二者不可共存
别忘了协同 swappiness
脏页和 swap 是内存压力下的两条出路,要一起看:
- 对数据库、Redis 等内存密集型服务,建议
vm.swappiness=10,避免因内存紧张被迫 swap,挤占本可用于缓存的空间 - 如果
swappiness设太高(如默认 60),系统可能在脏页还没来得及刷出前,就先开始 swap,进一步恶化 I/O 压力











