Linux iowait 很高怎么办?从磁盘等待到进程读写的排查思路

先判断是不是磁盘在拖慢系统

Linux 服务器卡顿时,很多人第一反应是看 CPU 使用率和内存剩余量。但线上排障里经常会遇到一种情况:CPU 看起来没有打满,内存也没有明显耗尽,网站、数据库或后台任务却明显变慢,登录 SSH 后敲命令也有延迟。这时就要特别注意 iowait。

Linux iowait 磁盘 I/O 排查示意图
iowait 排查要从整体等待、磁盘设备和进程读写三层逐步缩小范围。

iowait 可以简单理解为:CPU 本来可以继续干活,但正在等待磁盘或块设备完成读写。它不是一个单独的故障原因,而是一个信号,提示系统瓶颈可能不在计算能力,而在存储读写、文件系统、数据库刷盘、日志写入或云盘性能上。

判断 iowait 不能只看某一个瞬间的数值。如果偶尔跳高,很可能只是备份、日志轮转、定时任务或一次批量查询造成的短暂波动;如果连续多分钟维持较高水平,并且业务响应同时变慢,就值得进入磁盘链路排查。

用 top 和 vmstat 看整体趋势

最直观的入口是 top。打开 top 后,注意 CPU 行里的 wa 字段,它就是 iowait 的常见展示位置。如果 wa 长时间超过 10% 到 20%,同时业务响应变慢,就说明磁盘等待已经开始影响系统体感。

不过 top 更适合快速观察,不适合做趋势判断。进一步可以用 vmstat,例如执行 vmstat 1 10,每秒输出一次系统状态,连续看十次。这里重点看 wabr 几列:wa 代表等待磁盘的比例,b 代表不可中断睡眠的进程数量,r 代表等待 CPU 的进程数量。

如果 wa 高、b 也高,而 r 不高,通常说明不少进程卡在 I/O 等待上;如果 r 很高但 wa 不高,问题更可能在 CPU 调度;如果 wa 和内存换入换出一起升高,还要怀疑内存不足导致频繁 swap,把磁盘也拖慢了。

用 iostat 找到是哪块盘慢

确认存在 I/O 等待后,就要从“系统整体很慢”缩小到“哪块设备慢”。常用工具是 iostat,很多系统需要先安装 sysstat 包。执行 iostat -xz 1 10 后,可以看到每块磁盘的读写吞吐、请求等待时间和利用率。

这里不要只盯着 MB/s。对业务来说,延迟往往比吞吐更关键。重点关注 awaitr_awaitw_await%util。await 表示请求平均等待时间,数值越高,说明读写排队越明显;%util 接近 100% 时,表示这块设备已经非常忙。

如果某块盘的 await 明显高于其他盘,或者 %util 长时间接近满载,就要继续确认它对应哪个挂载点。可以用 lsblkdf -hmount 对照设备名和目录,判断是系统盘、数据盘、数据库目录还是日志目录在承压。

找到真正制造 I/O 的进程

知道磁盘忙还不够,还要找到是谁在制造读写。比较直接的工具是 iotop。执行 iotop -oPa 可以只显示正在产生 I/O 的进程,并按累计读写观察。线上机器如果不方便安装 iotop,也可以结合 pidstat -d 1 观察进程级读写。

常见的高 I/O 来源包括 MySQL 大查询和刷盘、日志文件暴涨、备份压缩任务、图片批量处理、缓存重建、容器镜像拉取、异常爬虫导致的访问日志写入,以及某些程序反复扫描目录。排查时不要急着重启服务,先确认它是在正常工作还是异常放大。

例如数据库在高峰期写入量上升,短时间 iowait 增加并不奇怪;但如果访问量不高,MySQL 仍持续大量读写,就要检查慢查询、临时表、索引缺失、binlog 或磁盘空间。日志进程持续写入时,则要看访问日志、错误日志和应用日志是否被异常请求刷屏。

区分磁盘慢、内存不够和云盘规格不足

iowait 高不一定代表磁盘坏了。很多时候,它是其他问题的结果。内存不足会让系统频繁使用 swap,看起来像磁盘问题;数据库索引不合理会把本该快速定位的数据变成大量随机读;日志级别开得太细,会让磁盘持续写小文件;备份策略不合理,则可能在业务高峰把 I/O 打满。

云服务器还要考虑云盘规格。不同云盘的 IOPS、吞吐和突发能力不一样,轻量业务平时看不出差异,一到备份、促销、采集或数据库写入高峰,就可能出现等待时间上升。如果业务长期依赖数据库和频繁写入,选择云服务器时就不能只看 CPU、内存和带宽,磁盘类型、IOPS、快照策略同样重要。

如果是面向企业网站、后台系统或跨境业务部署,可以在选型阶段把存储性能和线路一起评估。像速维云这类云服务器方案,实际落地时也需要结合访问地区、数据库规模、备份周期和业务峰值来判断配置,而不是只按最低价格下单。

处理顺序要先止血再优化

线上遇到 iowait 持续升高,第一步是止血。先暂停或错峰备份、压缩、批量导入、图片处理等非核心任务;如果是日志暴涨,先定位异常请求并临时限流;如果是数据库慢查询,要先找到最重的 SQL,必要时临时加索引、限制报表范围或把批处理移到低峰。

第二步是把证据留住。记录 top、vmstat、iostat、iotop 或 pidstat 的关键输出,同时保存业务慢的时间点、访问量、数据库连接数、慢查询日志和系统日志。不要只凭“当时很卡”判断原因,否则下一次复盘很难确认到底是磁盘、内存、数据库还是定时任务。

第三步再做长期优化。可以从减少无效日志、优化数据库索引、拆分冷热数据、调整备份时间、升级云盘规格、增加缓存、把附件和静态资源迁移到对象存储或 CDN 等方向入手。不同业务的答案不一样,但原则相同:先找出持续制造 I/O 的源头,再决定是优化程序、调整架构还是升级资源。

常用排查命令清单

入门排查可以按这个顺序执行:先用 top 看 wa 是否持续偏高;再用 vmstat 1 10 判断系统是在等磁盘还是等 CPU;然后用 iostat -xz 1 10 找出哪块磁盘延迟和利用率异常;最后用 iotop -oPapidstat -d 1 找到具体进程。

如果怀疑内存不足,同时看 free -hvmstat 里的 si/so,以及是否存在大量 swap;如果怀疑磁盘空间或 inode 问题,补充执行 df -hdf -i;如果怀疑数据库,继续看慢查询日志、连接数、临时表和磁盘目录。

排查 iowait 的核心不是背命令,而是建立链路:先看整体症状,再定位设备,再定位进程,最后回到业务行为。只要顺序清楚,就不会在 CPU、内存、磁盘、数据库之间来回猜。

© 版权声明
THE END
喜欢就支持一下吧
点赞6 分享