这个坑值得记一笔。一台 8 核 32G 的 CentOS 7 跑日志写入服务,为提升吞吐把 vm.dirty_ratio 从 20 调到 60,结果每隔十几分钟业务就整体卡顿,sar 里 %iowait 冲到 90。
刚开始盯着「云盘的突发额度被瞬时回写打满,后续写请求排队等待」,折腾了半个多小时,排掉了。
这类报错背后常见的原因有几处,逐个排除就行。脏页允许占用的比例过高,累积到阈值后内核一次性回写,所有写操作同时阻塞;dirty_expire_centisecs 太长,脏页在内存里待太久,集中落盘时形成毛刺;业务用 buffered write 且没有 fsync 节奏,脏页堆积速度超过回写能力。
动手时先看脏页堆积情况
grep -E 'Dirty|Writeback' /proc/meminfo
然后把脏页比例改回保守值
sysctl -w vm.dirty_ratio=15 vm.dirty_background_ratio=5
缩短脏页驻留时间,让回写更平滑
sysctl -w vm.dirty_expire_centisecs=1500
剩下的就是把配置固化并观察毛刺是否消失
echo 'vm.dirty_ratio = 15' > /etc/sysctl.d/90-dirty.conf && sar -b 1 10
别只看报错消失,验证要多做一步。/proc/meminfo 里 Dirty 稳定在几百 MB 以内,sar 的 %iowait 不再出现尖峰,业务接口的 p99 回到正常区间并持续一小时无毛刺。
这里还有个坑。调大脏页比例等于拿数据安全换吞吐,掉电时丢失的量也随之变大;数据库和日志类服务本就该自己控制刷盘节奏。如果同一现象隔几天又出现,说明根因没找到,别当偶发处理。
