
Linux 磁盘延迟高,通常不是单一原因导致的,而是 I/O 路径中多个环节叠加的结果。排查时需从应用层、文件系统层、块设备层到物理磁盘逐层下钻,避免直接跳到硬件结论。
看懂 iostat 输出里的关键指标
iostat -x 1 是最常用的初步诊断命令,重点关注以下几列:
- await:I/O 请求在队列中等待 + 实际服务的平均时间(毫秒),持续 > 10ms 需警惕;
- r_await / w_await:分别表示读/写请求的平均响应时间,可判断是读密集还是写密集导致延迟;
- %util:设备忙于处理 I/O 的时间百分比,接近 100% 说明设备饱和,但 SSD 场景下该值参考价值下降;
- avgqu-sz:平均队列长度,持续大于 1 表示请求开始堆积;
- svctm(已弃用,内核 2.6.38+ 不再准确):不要依赖此项,以 await 为准。
定位是“真慢”还是“假堵”
磁盘延迟高 ≠ 磁盘本身故障。常见干扰因素包括:
- 脏页回写压力:大量 write() 后未及时 sync,触发内核集中 flush(查看 /proc/vmstat 中 pgpgout、pgmajfault 及 bdi 相关统计);
- I/O 调度器不匹配:CFQ 在 SSD 上反而拖慢性能,建议 NVMe 用 none,SATA SSD 用 deadline 或 mq-deadline;
- 文件系统日志模式:ext4 默认 data=ordered,大文件写入可能阻塞;journal 模式下元数据写入也会串行化;
- 透明大页(THP)+ 内存回收:在高 I/O 场景下触发 compaction 或 direct reclaim,间接拉高 I/O 延迟(检查 /proc/vmstat 中 pgmajfault、pgpgin)。
深入追踪具体进程和 I/O 模式
用更细粒度工具确认谁在发什么请求:
- pidstat -d 1:按进程维度看每秒读写字节数、I/O 等待时间(%iowait);
- iotop -o:实时观察哪些进程正在做实际 I/O(-o 只显示有 I/O 的进程);
- bpftrace 或 biosnoop(bpftrace -e 'kprobe:blk_mq_start_request { printf("pid=%d cmd=%s\n", pid, args->rq->__cmd[0]) }'):抓取单个 I/O 请求的发起者和命令类型(如 READ/WRITE/FUA);
- cat /sys/block/*/queue/scheduler 和 /sys/block/*/rotational:确认调度器是否生效、内核是否正确识别 SSD(rotational=0)。
检查底层硬件与驱动状态
排除软件层问题后,再查硬件相关线索:
- smartctl -a /dev/sdX:关注 Reallocated_Sector_Ct、Current_Pending_Sector、UDMA_CRC_Error_Count;
- dmesg | grep -i "ata\|nvme\|error\|timeout":查找链路层错误、重试、link reset 等;
- lsblk -d -o NAME,ROTA,RAND,LOG-SEC,PHY-SEC:确认逻辑/物理扇区大小是否对齐(尤其虚拟机或 LVM 场景);
- 检查 RAID 卡缓存策略:WriteBack 未配 BBU 或电池失效时,控制器会自动降级为 WriteThrough,性能暴跌;用 MegaCli 或 storcli 查看 Cache Policy 和 BBU 状态。










