Linux IO等待过高本质是CPU空闲时等待磁盘响应,需结合await、avgqu-sz和%iowait交叉判断:await超阈值(HDD>10ms/SSD>1ms)、avgqu-sz长期>1、%iowait持续>10%且伴随高await可锁定瓶颈;再用iotop、pidstat、lsof等定位进程及IO模式,排除%util高但无卡顿等误判,最后从数据库、日志、文件系统和应用层优化IO路径。

Linux IO等待过高,本质是CPU在空闲时仍需等待磁盘响应,说明I/O路径存在延迟或阻塞。关键不是看%util是否爆满,而是结合await、avgqu-sz和iowait三者交叉判断——尤其当%util高但系统不卡顿,大概率是SSD/NVMe深队列下的高吞吐常态,而非真正瓶颈。
盯紧三个核心指标
用 iostat -x 1 每秒刷新,重点关注:
- await:平均I/O请求总耗时(毫秒)。HDD持续>10ms、SSD持续>1ms,即需警惕;若r_await远高于w_await,说明读操作拖慢整体;
- avgqu-sz:平均队列长度。长期>1表示请求堆积,>4往往意味着应用发得太猛或底层处理不过来;
- %iowait(来自top或iostat CPU部分):CPU空闲却等IO,持续>10%且伴随高await,基本可锁定IO瓶颈;单独高iowait但await正常,可能是单次大IO或误报,需结合进程排查。
快速定位“真凶”进程
%util和await异常后,立即用iotop揪出具体目标:
- 运行 sudo iotop -o -P,只显示有IO活动的进程(-o)并按进程聚合(-P);
- 按 P 键按IO使用率排序,一眼识别TOP消耗者;
- 对准高IO进程PID,执行 pidstat -d -p PID 1,观察rkB/s、wkB/s及rrqm/s/wrqm/s——若合并数(rqm)极低而IOPS(r/s、w/s)极高,基本是小块随机IO,比如数据库索引扫描或日志刷盘;
- 再用 lsof -p PID 查它打开的文件,配合 filefrag -v 文件路径 看是否碎片严重,加剧寻道开销。
区分真假瓶颈,避免误判
以下情况容易误导判断,需主动排除:
- %util接近100%但无卡顿:SSD/NVMe并发能力强,高%util常对应高吞吐+深队列,此时应看await是否可控,而非盲目降负载;
- iowait高但top里CPU占用低:完全正常。IO密集型进程多数时间处于不可中断睡眠(D状态),不计入CPU使用率,但会被iotop捕获;
- fio测试结果与生产偏差大:默认配置太理想化。务必加 --ioengine=libaio --direct=1 模拟数据库直写,用 --filename 指向业务盘,并在测试前清缓存:echo 3 > /proc/sys/vm/drop_caches。
从源头优化IO路径
确认瓶颈后,优先从软件层入手,成本低见效快:
- 数据库类服务:检查慢查询日志,为高频WHERE字段补索引,避免全表扫描引发随机读;调整innodb_io_capacity(MySQL)或shared_buffers(PostgreSQL)匹配磁盘能力;
- 日志类服务:将DEBUG/INFO日志级别下调,启用异步写入(如log4j2的AsyncLogger),并配置logrotate自动轮转压缩;
- 文件系统层:SSD建议用noop或none调度器(内核5.0+),HDD可用bfq提升公平性;挂载选项加 noatime,nodiratime,commit=60 减少元数据更新;
- 应用逻辑:小文件合并写入、用mmap替代read/write、预分配大文件减少扩展碎片。










