先看 iostat -x 1 的 %util 和 await:若 %util 接近 100% 且 r/s/w/s 很低,说明请求排队严重;await > 50ms 且远大于 svctm,表明设备响应慢或队列积压;NVMe 盘需重点关注 avgqu-sz 和 r_await/w_await。

确认磁盘 I/O 是否真瓶颈
别急着查内核参数或重装驱动,先看 iostat -x 1 输出里 %util 和 await 是否持续高位。如果 %util 接近 100% 但 r/s/w/s 很低,说明请求排队严重;若 await > 50ms 且 svctm(已弃用,仅作参考)远小于它,大概率是设备响应慢或队列积压。注意:NVMe 盘的 %util 意义弱化,得重点看 avgqu-sz 和 r_await/w_await。
区分是随机 I/O 还是顺序 I/O 下降
用 iotop -o -a 找出高 IO 的进程,再结合 lsof -p $PID 看它在读写哪些文件;接着用 blktrace -d /dev/nvme0n1 -w 10 -o - | blkparse -i - 抓取原始请求模式——R(read)和 W(write)后面带 Q(queue)还是 M(merge)多,能判断是否大量小块随机访问。数据库、Elasticsearch 日志写入、容器镜像拉取常触发这类模式,而备份工具(如 rsync --whole-file)或大文件拷贝则倾向顺序 I/O。
检查底层存储路径是否存在隐性限速
常见却被忽略的点:
- 云盘挂载时用了
noatime,nobarrier但没关discard,导致频繁 TRIM 拖慢写入 - 使用 LVM 时,逻辑卷启用了
mirror或snapshot,I/O 路径变长且元数据开销上升 - RAID 卡缓存策略被设为
WriteThrough(直写),而非WriteBack(回写),尤其在无 BBU/超级电容保护时会被系统强制降级 - NVMe 多路径(如
nvme-cli配置的mpath)中某条路径掉线,剩余路径负载不均却未告警
查 RAID 卡状态用 /opt/MegaRAID/MegaCli/MegaCli64 -AdpAllInfo -aALL,看 Cache Policy;查 NVMe 路径用 lsblk -S 和 cat /sys/block/nvme0n1/device/physical_node。
警惕内核 I/O 调度器与队列深度错配
SSD/NVMe 默认应禁用电梯调度器,但某些发行版(如旧版 CentOS 7)仍默认启用 cfq 或 deadline。运行 cat /sys/block/nvme0n1/queue/scheduler,输出应为 [none];如果不是,临时切到 none:echo none > /sys/block/nvme0n1/queue/scheduler。同时检查队列深度:cat /sys/block/nvme0n1/device/queue_depth,低于 128 可能限制并发能力——部分 PCIe Gen3 x4 NVMe 盘需手动设为 256(通过 nvme set-feature 或启动参数 nvme_core.default_ps_max_latency_us=0)。
真正难定位的是混合场景:比如一个 K8s 节点上既有高吞吐日志写入,又有低延迟数据库 Pod,它们共享同一块 NVMe,但 cgroup v1 的 blkio.weight 对 NVMe 支持有限,v2 的 io.weight 又依赖内核版本 ≥ 5.0 ——这种时候看到吞吐下降,问题其实在隔离机制失效,而不是磁盘本身。










