Linux 服务器 IO wait 高意味着什么
iowait(也叫 %wa 或 %iowait)是 Linux 性能监控中最容易被误读、但又最有诊断价值的指标之一。
一、iowait 到底是什么?(内核视角)
在 Linux 的 CPU 时间统计中,每一秒的 CPU 时间都会被拆分成以下几类:
- %usr:用户态进程消耗的 CPU 时间
- %sys:内核态(系统调用、调度、驱动等)消耗的 CPU 时间
- %idle:CPU 完全空闲,没有任何任务可执行
- %iowait:CPU 处于空闲状态,但有进程在等待磁盘 I/O 完成,无法被调度执行其他任务的时间占比
- %irq / %soft:硬中断 / 软中断处理时间
- %steal(虚拟化可见):被 hypervisor 偷走的时间
最核心的一句话:
iowait 高 ≠ 磁盘很忙 iowait 高 = 有进程在等待磁盘 I/O 完成,而 CPU 此时无事可做
换句话说: iowait 是 CPU 的“无聊等待时间”,它本质上是 进程在 D 状态(不可中断睡眠,通常是等待块设备 I/O) 导致的 CPU 空转时间。
二、iowait 高的几种典型含义对比
| iowait 值(持续) | %util(iostat) | await(平均每次 IO 时长) | 真实含义(最可能的情况) | 常见业务场景 |
|---|---|---|---|---|
| 很高(>30–60%) | 很高(>80–95%) | 中等~高(10–50ms+) | 磁盘真的饱和了,IO 请求排长队 | 数据库随机读写、日志狂写、binlog/WAL 同步写 |
| 很高(>40–70%) | 中等~高 | 极高(>50–200ms) | 单次 IO 非常慢(队列不长,但每个请求都卡很久) | 网络存储(NFS/EBS gp2)、坏盘/RAID 降级、机械盘尾部延迟 |
| 中等(15–30%) | 中等 | 中等 | 有一定 IO 等待,但不严重,可能被其他因素放大 | 高并发小文件元数据操作、脏页回写压力 |
| 很低(<5–10%) | 很低 | — | 基本没有 IO 等待,load 高是其他原因 | CPU 计算密集、锁竞争、大量 futex 等待 |
三、iowait 高的真正含义总结(最重要几条)
- iowait 高说明 CPU 在“等人” CPU 已经没有可运行的任务了,但有进程在 D 状态等着磁盘完成 IO,所以 CPU 被“浪费”在等待上。
- iowait 高不一定代表磁盘性能差
- 可能是磁盘真的饱和了(%util 接近 100%)
- 也可能是少数非常慢的 IO 拖住了整个队列(await 很高但 %util 不满)
- 还可能是大量进程同时在等 IO(即使磁盘不饱和,等待人数多也会推高 iowait)
- iowait 高通常伴随 load average 异常升高 因为 D 状态的进程也会被计入 load average(uninterruptible sleep 算在 load 里),所以经常出现“CPU 不忙、load 却很高”的经典假象。
- 现代 NVMe + 多队列调度下,iowait 的参考意义在下降 在高性能 NVMe SSD + mq-deadline/none 调度器 + 多队列环境下,即使吞吐很高,iowait 也可能保持较低(因为 CPU 可以快速切换去做其他事)。此时更应该关注 await 和 avgqu-sz(平均队列长度)。
四、iowait 高时最该执行的排查组合(推荐顺序)
- iostat -x 1 5 → 看 %util、await、avgqu-sz、r/s、w/s、rMB/s、wMB/s → 判断是随机读/写、顺序读/写,还是单次 IO 极慢
- iotop -o 或 pidstat -d 1 5 → 定位到底是哪个进程/线程在产生大量读写
- vmstat 1 5 → 看 wa(iowait)、b(阻塞进程数)、bi/bo(块读写)
- lsof | grep deleted 或 lsof +L1 → 检查是否有被删除但还在写的文件(最常见日志文件被 logrotate 删掉)
- iostat -x + sar -d(历史) → 回溯问题发生前后的 IO 变化趋势
五、常见误区与澄清
- 误区 1:iowait 高就说明磁盘坏了 → 不一定,可能只是业务写模式不友好(大量同步小块随机写)
- 误区 2:iowait 高就应该加 SSD / 加大 IOPS → 先优化写策略(异步日志、调 innodb_flush_log_at_trx_commit、降日志级别)往往效果更好
- 误区 3:iowait 为 0 就没 IO 问题 → 现代多队列 NVMe 下可能 iowait 很低,但 await 很高,一样慢
一句话总结:
iowait 高本质上是“CPU 在等磁盘”,说明有进程被卡在 D 状态等待块设备完成 IO。 它是一个“CPU 无聊程度”的指标,而不是“磁盘忙碌程度”的直接指标。 真正要看的是 %util + await + avgqu-sz + 哪个进程在写/读。
你现在服务器的 iowait 大概多少? 有没有同时看到 %util 和 await 的值? 是数据库、日志、还是其他业务产生的 IO?可以贴一下 iostat -x 1 5 或 iotop 的输出,我们一起判断具体原因和优化方向。