查看 Linux 具体进程 IO 读写带宽占用,最准确、最高效的方式是使用sudo iotop -o -P:其中,-o 参数只显示当前真正发生 IO 读写的进程,能够过滤掉约 95% 的无效干扰信息;-P 参数则仅显示进程,不展开线程,便于快速判断到底是哪一个进程在占用磁盘带宽。界面中的 DISK READ 和 DISK WRITE 列会显示自动缩放后的实时读写带宽,单位通常为 B/s、K/s、M/s,默认每秒刷新一次。如果想按 IO 等待情况排序,快速找出高延迟进程,可以直接按下 Shift+P 组合键。

直接用 iotop -o -P 查看实时带宽最准确
如果你想在 Linux 系统中快速查看“哪个进程正在大量占用磁盘 IO”,通常不需要猜测,也不用额外写脚本,sudo iotop -o -P 就是生产环境中排查进程磁盘读写带宽的首选命令。它默认每秒刷新一次,DISK READ 和 DISK WRITE 两列展示的就是当前进程的实时读写速率,单位会自动缩放为 B/s、K/s、M/s。
-o是最关键的参数:只展示当前确实在进行磁盘读写的进程,能有效过滤掉内核线程和静默进程(例如[kthreadd]、[jbd2/sda-8]),否则终端里大部分内容都会变成无意义噪音-P可以避免线程信息干扰判断:同一个进程的多个线程默认会分散显示在多行中,加上-P后只保留进程级视图,更方便横向比较不同进程的 IO 占用情况- 在界面中按
Shift+P可切换为按IO>列排序——某些高频小文件读写的进程(如日志轮转)虽然带宽数值不高,但 I/O 等待比例可能达到 90% 以上,用这种方式更容易快速定位 - 不建议直接使用默认不带参数的
iotop:如果没有-o,你基本就是在一堆 0.00 B/s 的记录里找有效数据,排查效率会非常低
pidstat -d 1 更适合脚本监控或查看指定进程 IO
如果你的目标是编写监控脚本,或者只需要持续观察某几个指定进程(例如 mysqld、某个 python 服务),那么 pidstat -d 往往比 iotop 更轻量,输出格式也更加结构化,更适合做自动化分析。
- 必须带上采样时间间隔,例如
pidstat -d 1:如果不带参数,它只会输出一次快照;而执行pidstat -d 0会导致终端卡住,不建议尝试 - 重点关注
rkB/s和wkB/s两列:它们表示实时读写速率,单位是 KB/s,不是累计值,也不是缓存命中量,而是真实的块设备读写速度 - 查询特定进程时,推荐结合
pgrep使用:例如pidstat -d 2 -p "$(pgrep -f 'gunicorn.*wsgi')",相比手动执行ps aux | grep更稳定可靠,尤其适合命令行参数较复杂的服务进程 - 需要注意:非 root 用户运行时,可能无法完整看到 systemd、内核线程等进程;另外在容器环境中,它显示的通常是宿主机视角下的 IO 信息,而不是 cgroup 限制后的最终值
为什么不能只看 /proc/[pid]/io 的 read_bytes/write_bytes
很多人会直接查看 /proc/[pid]/io 文件中的 read_bytes 和 write_bytes,但这两个字段反映的是进程累计的磁盘读写字节数,并不是实时带宽。如果你想计算进程 IO 带宽,必须手动做前后两次差值再除以时间间隔,这种方式在实际排查时很容易出现误判。
read_bytes的确只统计实际从块设备读取的字节数,不包含 page cache 命中,但它本身没有时间戳,所以两次执行cat /proc/1234/io | grep read_bytes的结果差值,完全依赖你的采样时间是否稳定- 如果某个进程刚刚完成一轮大规模读取,而你采样时它正处于休眠阶段,那么计算出来的差值可能就是 0;下一秒它重新开始读取,你又刚好没有采到,这时看起来像“没有带宽占用”,其实只是采样节奏错开了
iotop和pidstat底层虽然也是通过轮询这些数据实现,但它们已经帮你完成了周期性平滑采样(默认 1 秒间隔),因此更接近运维排查时所需要的“实时 IO 带宽”视图- 还有一个经常被忽略的点是:
read_bytes并不等于物理磁盘层面真实发生的所有读取量——例如 RAID 控制器或 NVMe 控制器内部的重试、对齐写入等行为,内核层统计可能无法完全覆盖
看到高 IO 不要急着 kill,先判断是“进程占用高”还是“磁盘性能弱”
iotop 或 pidstat 能告诉你“到底是谁在读写磁盘”,但它们并不能直接说明“为什么会慢”或者“这种高 IO 是否真的异常”。因此,在发现某个进程 IO 很高之后,最好继续做交叉验证。
- 如果
iotop显示ja va进程的DISK WRITE持续在 30M/s 左右,建议先执行iostat -x 1查看磁盘设备级指标:在 SATA 或 SSD 场景下,如果await > 20ms或%util > 80%,通常说明磁盘本身已经接近饱和,这时直接杀进程往往解决不了根因 rsync或tar出现高 IO 并不一定是异常,很多时候这是正常备份或归档行为;不过最好结合cat /proc/确认它处理的确实是业务数据,而不是误操作扫描了整个/cmdline | tr ' ' ' ' /目录- 如果
mysqld长时间维持高写入,原因可能是innodb_log_file_size设置过小,导致 checkpoint 触发过于频繁;相比单纯盯着 IO 指标,检查SHOW ENGINE INNODB STATUS中的 Log sequence number 变化会更准确 - 还有一种很容易被忽视的情况:高 IO 只是表面现象。比如某个
ja va进程的SWAPIN%也很高,就说明系统可能存在内存不足并发生 swap,此时磁盘 IO 高只是连带结果,真正应该优先检查的是free -h和vmstat 1,而不是继续单独优化磁盘
