iotop 显示的是进程当前每秒提交到块设备的实际读写字节数(KiB/s 或 MiB/s),非累计值、非文件级统计,不包含 page cache 内部操作;-o 仅显示活跃 I/O 线程,-P 可按进程聚合,需配合 lsof 和 /proc/PID/io 定位具体文件。

iotop 显示的 READ/WRITE 值到底对应什么
iotop 默认显示的是进程当前每秒的 I/O 字节数(不是累计值,也不是缓冲区大小),单位是 KiB/s 或 MiB/s。它反映的是内核提交到块设备层的实际读写流量,不包含 page cache 内部操作或未刷盘的脏页。
常见误解是把它当成“文件读写量”,其实它统计的是底层块设备 I/O——比如一个 dd 写 1GB 文件,如果全走缓存,初期 WRITE 可能几乎为 0;等 sync 或脏页回写时才爆发式出现。
-
iotop -o只显示正在做 I/O 的线程(过滤掉 idle 状态),比默认视图更聚焦 - 按
P键可按 I/O 百分比排序,比按字节数更直观反映资源争抢程度 - 注意区分
DISK READ和DISK WRITE列:前者是磁盘读取量,后者是写入量;SWAPIN和IO>列只在特定内核版本中可见,不可依赖
为什么 top 里看不到 iotop 列出的进程
因为 iotop 抓的是线程级 I/O(LWP),而 top 默认按进程聚合显示。同一个进程的多个线程可能分别在读不同文件,iotop 会把它们拆成多行,top 却只算作一个 PID。
典型场景:Java 应用用多个线程并发写日志,iotop 里能看到 5 个 java 线程各自有 2MiB/s WRITE;但 top 里只看到一个 java 进程,%CPU 可能不高,I/O 相关指标也不体现。
- 用
iotop -P强制按进程聚合(合并同 PID 所有线程),数值更接近运维直觉 - 若需定位具体文件,得配合
lsof -p <pid></pid>或/proc/<pid>/fd/</pid>查看打开的 fd,再用readlink解析路径 - 注意:容器环境里,
PID是宿主机视角的,lsof需在宿主机执行,且要确保容器未用--pid=host外的隔离模式
非 root 用户运行 iotop 报错 “unable to set thread io priority”
iotop 启动时尝试调用 ioprio_set() 设置 I/O 调度优先级,这需要 CAP_SYS_ADMIN 能力。普通用户没权限,就会报这个错——但不影响核心监控功能,只是无法动态调整优先级。
错误信息本身是 warning,不是 fatal,界面仍可刷新、排序、显示数据。别被吓住以为不能用。
- 最简解法:
sudo iotop,别试图用setcap给二进制加权(有安全风险,且多数发行版不支持) - 如果必须免密码,配
sudoers:添加%monitor ALL=(ALL) NOPASSWD: /usr/bin/iotop,然后用sudo iotop - 某些云主机(如 AWS EC2)内核禁用了
CONFIG_TASK_DELAY_ACCT,会导致 iotop 完全无法启动,此时只能换用pidstat -d 1或/proc/PID/io手动解析
想看某个进程正在读写的文件,但 lsof 输出太多干扰项
lsof -p <pid></pid> 列出所有打开的 fd,但包括 socket、pipe、eventfd 等非磁盘文件。真正涉及读写的,得筛出类型为 REG(普通文件)且访问模式含 u(read/write)或 w(write-only)的条目。
更准的做法是结合 /proc/<pid>/io</pid> 确认活跃度,再过滤 lsof:
lsof -p 1234 | awk '$5 ~ /REG/ && $4 ~ /[uw]/ {print $9}' | xargs -r ls -lh 2>/dev/null
-
$4是 FD 列(如txt、mem、3u),u表示 read+write,w表示 write-only -
$5是 TYPE 列,REG才是磁盘文件;DIR、FIFO、sock都不是目标 - 注意符号链接路径可能指向 /dev/zero、/dev/null 等伪设备,这种不算“真实文件读写”,要人工排除
真要实时跟踪文件级 I/O,inotifywait 或 auditd 更合适,但开销大、配置重;iotop + lsof 是快速定位的合理折中。











