用 iotop -o 实时定位狂写磁盘进程,需 root 权限;iostat -x 关注 await、avgqu-sz 而非 %util;dd 测速需用 fio 模拟真实负载;调优 vm.dirty_* 参数须兼顾刷盘平滑性与设备特性。

怎么快速定位哪个进程在狂写磁盘
用 iotop 是最直接的办法,它像 top 一样实时显示每个进程的 I/O 读写速率。注意加 -o 参数只显示有实际 I/O 的进程,否则一堆休眠进程会干扰判断;如果没装,Debian/Ubuntu 用 sudo apt install iotop,CentOS/RHEL 用 sudo yum install iotop(或 dnf)。别依赖 ps 或 htop——它们根本不暴露 I/O 带宽数据。
- 运行时需 root 权限,普通用户看不到其他进程的 I/O 细节
- 默认按 I/O 总量排序,但实际瓶颈常是 IOPS(每秒请求数)而非吞吐量,可按
P键切换到“IO_RATE”列观察写延迟敏感型负载 - 某些容器环境(如使用
io.weightcgroup v2)下,iotop显示的数值可能偏低,此时得结合cat /sys/fs/cgroup/io.stat手动核对
为什么 iostat -x 1 的 %util 接近 100% 却没卡死
%util 只表示设备忙的时间占比,并不等于饱和。SSD 和 NVMe 设备能并行处理成百上千个队列请求,即使 %util 满了,只要 await(平均 I/O 等待时间)低、svctm(服务时间)稳定,系统响应就正常。真正危险的是 r_await 或 w_await 持续超过 10ms(机械盘)或 1ms(NVMe)。
-
iostat -x 1中重点盯avgqu-sz(平均队列长度):持续 > 1 表示请求开始排队;> 4 通常说明底层设备已吃紧 -
%util对 NVMe 设备参考价值极低,建议直接看rqm/s(合并请求数)和rrqm/s/wrqm/s判断 I/O 合并效率 - 虚拟机里看到高
%util,先检查宿主机的blktrace输出,可能是上层存储(如 Ceph、LVM thin pool)导致的假性繁忙
dd 测速结果为什么和实际应用差十倍
dd 默认用小块(512B–4KB)、同步写(conv=fdatasync 才算真正落盘),测出来的是随机写或小文件写极限,而数据库、日志服务多是混合读写+大块顺序写+缓存参与。它反映的是“最差路径”,不是典型负载。
- 模拟数据库场景:用
fio --name=randwrite --ioengine=libaio --rw=randwrite --bs=16k --numjobs=4 --runtime=60 - 绕过页缓存加
--direct=1,否则dd结果全是内存带宽,跟磁盘无关 - 生产环境禁用
oflag=sync测吞吐——这会让每次写都等刷盘,压垮队列深度,测出的是延迟而非吞吐
调整 vm.dirty_ratio 后反而更卡了
调高这个值(比如从 20 改到 60)本意是让内核攒更多脏页再刷盘,提升吞吐。但若应用本身写入节奏不均(例如批量导入后突发 flush),会导致刷盘时集中触发大量 writeback,造成数秒级 I/O 尖峰,表现为周期性卡顿。
- 优先调
vm.dirty_background_ratio(后台异步刷起点),设为 10–15,让刷盘更平滑 - 配合
vm.dirty_expire_centisecs(脏页存活上限,默认3000=30秒),避免脏页积压太久 - SSD 上慎用极高
dirty_ratio,因频繁擦除+写放大可能加速磨损,且 TRIM 命令无法及时回收空间











