vmstat bi/bo 极高但无明显 IO 进程的 page cache 回写压力分析

高bi/bo但top/iotop无活跃IO进程,通常是内核后台刷脏页(flush-*线程)所致,因vmstat统计内核级IO而上层工具仅显示用户态进程;可通过/proc/meminfo查Dirty/Writeback、perf抓块层请求、调低dirty_background_ratio验证。

vmstat bi/bo 极高但无明显 io 进程的 page cache 回写压力分析

bi/bo 高但 topiotop 看不到活跃 IO 进程?先确认是不是 page cache 回写

这是典型「磁盘在忙,但人找不到谁在用」的场景。根本原因往往是内核在后台批量回写脏页(dirty pages)到磁盘,而这些操作不绑定具体用户进程,iotop 默认只显示用户态进程的 IO,top 更是完全不展示 IO 源头。vmstatbi(块读)和 bo(块写)是内核级统计,真实反映底层块设备活动,所以它“看得见”,而上层工具“看不见”。

  • bo 持续 > 1000(单位:blocks/s)且 wa > 15%,同时 free 内存充足、swpd = 0 → 基本可排除 swap 压力,聚焦 page cache 回写
  • 运行 cat /proc/vmstat | grep -E "pgpgin|pgpgout|pgmajfault|pgpgin",若 pgpgout(页出)速率远高于 pgpgin(页入),说明大量脏页正被刷出
  • 检查 /proc/sys/vm/dirty_ratio/proc/sys/vm/dirty_background_ratio:若前者接近 80 且后者设为 10,而当前 dirty 内存已占物理内存 7–8%,就会触发激进回写

如何验证 page cache 是否正在高压回写

别只盯 vmstat 输出,要联动看内存脏页状态和内核回写行为:

  • 执行 grep -i dirty /proc/meminfo,重点关注:Dirty:(当前脏页 KB)、Writeback:(正在回写的 KB)、DirtyRatio:(触发直接回写的阈值 %)
  • watch -n 1 'cat /proc/meminfo | grep -i -E "dirty|writeback"' 动态观察:若 Dirty 在缓慢下降、Writeback 波动剧烈(如从 0 突增至 200MB+),就是后台回写线程(flush-*)在工作
  • 查进程:ps aux | grep flush,你会看到类似 [flush-253:0] 的内核线程 —— 它们不显示在 top 的 CPU 排行榜里,但确实在驱动磁盘写入

常见诱因与误判陷阱

不是所有高 bi/bo 都是“问题”,但容易被当成 IO 瓶颈误调:

微信 WeLM

微信 WeLM

WeLM不是一个直接的对话机器人,而是一个补全用户输入信息的生成模型。

下载

  • 日志服务突发刷盘:比如 rsyslogjournald 收集大量日志后,批量 fsync → 触发脏页集中回写,iotop 可能只看到瞬间的 journald 写入,但 vmstat 持续录到 bo 高峰
  • ext4 的 journal 提交:即使应用没显式写文件,ext4 日志机制也会周期性提交元数据,产生稳定 bo,尤其在小文件密集写场景下
  • 误把 buffer/cache 释放当压力:执行 echo 3 > /proc/sys/vm/drop_caches 后,bo 会飙升 —— 这是主动刷 cache,不是系统故障,但新手常因此 panic
  • RAID 卡缓存策略干扰:如果启用了 write-back 缓存但电池失效,控制器可能降级为 write-through,导致 bo 值虚高且延迟突增,此时 iostat -x%utilawait 才是关键指标

定位真实源头的三步实操法

绕过“看不到进程”的困境,直接抓内核 IO 路径:

  • 第一步:用 perf record -e block:block_rq_issue -a sleep 10 录制块层请求,再 perf script | head -20 看哪些进程/内核路径发出最多 WRITE 请求(注意:flush-* 线程会高频出现)
  • 第二步:检查 /sys/block/*/stat,对比各磁盘的第 5 列(写入完成次数)和第 9 列(写入扇区数),若某盘 bo 主要来自它,再查该盘挂载的文件系统是否有大日志、数据库 WAL 或临时文件目录
  • 第三步:临时降低回写激进度:echo 5 > /proc/sys/vm/dirty_background_ratio(让后台回写更早启动,避免堆积爆发),并观察 vmstat 1bo 是否从脉冲式变为平缓持续 —— 若是,就坐实了 page cache 管理策略问题

真正难处理的,从来不是 bo 多高,而是脏页生成速度长期超过磁盘持续写入能力。这时候调参数只是缓解,得回头查应用是否在频繁 open(O_SYNC)、是否日志轮转策略不合理、或容器里没限制 memory.swap.max 导致 cgroup 层面脏页失控 —— 这些细节,vmstat 不说,但数据在那儿。

https://www.php.cn/faq/2034305.html

发表回复

Your email address will not be published. Required fields are marked *