iotop显示的是进程调用read/write的逻辑字节数(rchar/wchar),含page cache,非真实落盘量;pidstat -d 1基于read_bytes/write_bytes,统计进入block layer的数据,更接近物理层真实i/o。

iotop 是唯一能直接看到每个进程实时读写量的命令,但它显示的是带缓存的逻辑量(rchar/wchar),不是真实落盘数据。真要定位“谁在刷盘”,必须用 iotop -o -d 1;若要接近物理层归属,则得切到 pidstat -d 1。
为什么 iotop 显示的不是真实磁盘读写
iotop 的 DISK READ 和 DISK WRITE 列来自 /proc/[pid]/io 中的 rchar/wchar 字段,代表进程调用 read(2)/write(2) 的字节数,含 page cache 缓存路径。比如一个进程反复读同一文件,iotop 可能显示几百 MB/s,但实际没发任何请求到磁盘。
- 它不反映是否绕过 cache(如
O_DIRECT) - 无法区分 mmap 读写和普通 read/write
- 数值单位自动缩放(B/s、K/s、M/s),但底层仍是字节计数,无请求频次信息
pidstat -d 1 更接近真实设备级归属
pidstat -d 1 的 rkB/s 和 wkB/s 列基于 /proc/[pid]/io 的 read_bytes/write_bytes,这个值只统计真正进入 block layer 的数据量(即绕过 cache 或被 cache miss 触发的 I/O)。它是目前最轻量、最可靠的方式,用于判断“哪个进程导致了磁盘真实吞吐”。
- 需 root 权限才能看到所有进程(否则只显示当前用户)
- 输出列名易混淆:
rkB/s≠iostat的rkB/s,前者 per-process,后者 per-device - 不显示请求次数(IOPS),所以看不出是大块顺序写还是小包随机写
- 刷新间隔建议设为 1 秒或 2 秒,太短会因采样抖动失真
别指望 top 或 htop 看磁盘 I/O
top 和 htop 根本不采集 I/O 数据 —— 它们连 /proc/[pid]/io 都不读。所谓“IO%”列是某些发行版打的补丁(如 Ubuntu 的 htop 衍生版),非标准行为,不可靠。
-
htop默认无磁盘 I/O 列,即使开启也依赖外部插件或伪造字段 -
top的%MEM和%CPU和磁盘无关,wa% 是 CPU 等待时间,不能反推进程级 I/O 量 - 试图用
lsof + du统计文件大小来估算读写量,纯属误导:文件大小 ≠ 实际访问量,更不等于落盘量
真要追到具体文件,得用 filetop 或 sysdig
当你从 pidstat -d 1 锁定高 I/O 进程后,下一步是看它在读写哪些文件。这时 iotop 无能为力,必须换工具:
-
/usr/share/bcc/tools/filetop 1 -a -p <pid></pid>:显示该进程每秒对每个文件的读/写次数和 KB 数,基于 eBPF,开销低、精度高 -
sysdig -c topfiles_bytes "proc.pid=<pid>"</pid>:输出按字节数排序的文件列表,适合快速抓大头,但需提前安装 sysdig - 慎用
lsof -p <pid> | grep REG</pid>:只能看到打开的文件,看不到读写方向、频率或吞吐,容易漏掉已关闭但仍在 buffer 中的数据
真正容易被忽略的是:所有进程级工具都只能告诉你“谁触发了 I/O”,但无法回答“这些 I/O 是否真的到达了物理介质”。要验证,必须比对 iostat -dx 1 的 r_ios/w_ios 和 /sys/block/*/stat 第 1/5 列(completed reads/writes)—— 中间差值就是 block layer 合并或驱动暂存的部分。











