iotop —— 按进程实时排查磁盘 IO(像 top 一样看 IO)
这个工具是做什么的
iostat 只到设备级(哪块盘忙),iotop 直接告诉你是哪个进程/线程在读写磁盘,是定位 iowait 元凶最快的一步。它读内核 taskstats,需要 root。
可以回答什么问题
| 问题 | 怎么用 |
|---|---|
| 哪个进程在大量读写磁盘? | iotop -o 只看有 IO 的进程 |
| 某个进程的 IO 等待时间占比多高? | IO> 列:接近 100% = 几乎全在等 IO |
| 是哪个线程在读/写? | iotop 默认线程模式(-P 切回进程聚合) |
| 进程在 swap 吗? | SWAPIN 列非 0 说明在等换入 |
数据来源
- 来源接口:内核 taskstats netlink 接口,提供每个进程/线程的实际读写字节、swapin、IO 等待占比。需内核开启
CONFIG_TASK_IO_ACCOUNTING。 - 采集方式:通过 netlink 向内核订阅 per-task 的 IO 统计,按间隔刷新。
- 由此决定的特性:① 需要 root(订阅 taskstats 的权限要求),普通用户/受限容器里跑不起来;② 正因为走 taskstats 而非读
/proc,才能给出pidstat -d没有的IO>(IO 等待占比)列;③ 容器里常因拿不到该接口失败,需--cap-add SYS_ADMIN或在宿主机跑。
bash
yum install iotop / apt install iotop
sudo iotop # 必须 root一、用法
bash
sudo iotop # 交互式实时刷新(默认按 IO 排序)
sudo iotop -o # --only:只显示当前有 IO 的进程(最常用,屏幕清爽)
sudo iotop -oP # -P 只看进程,不展开到线程
sudo iotop -a # --accumulated:显示自 iotop 启动以来的累计量,而非瞬时速率
sudo iotop -d 2 # -d 刷新间隔 2 秒
sudo iotop -u derek # 只看某用户
sudo iotop -p <PID> # 只看指定进程
sudo iotop -b -n 5 -o # --batch 批处理,输出 5 次到 stdout(无交互环境/写日志)
sudo iotop -boqqq -n 3 > io.log # 批处理 + 静默表头,纯数据落盘二、交互键
| 键 | 作用 |
|---|---|
o | 切换"只看有 IO 的进程"(等价 -o) |
p | 进程 / 线程视图切换 |
a | 累计 / 瞬时速率切换 |
← → | 移动排序列 |
r | 反转排序方向 |
q | 退出 |
三、输出与关键列
bash
Total DISK READ : 0.00 B/s | Total DISK WRITE : 42.50 M/s
Actual DISK READ: 0.00 B/s | Actual DISK WRITE: 40.10 M/s
TID PRIO USER DISK READ DISK WRITE SWAPIN IO> COMMAND
8922 be/4 derek 0.00 B/s 42.50 M/s 0.00 % 93.20 % cpu_demo- 顶部
Total是应用层发起的读写;Actual是最终落到磁盘的(差异来自页缓存/合并/延迟写)。 - 列:
| 列 | 含义 | 判读 |
|---|---|---|
DISK READ/DISK WRITE | 该进程/线程每秒读/写磁盘速率 | 找吞吐大户 |
SWAPIN | 换页读入占比 | 高 = 内存不足,进程在等被换出的页换回来 |
IO> | 该进程花在等待 IO 上的时间百分比 | 接近 100% = 它几乎一直在等 IO,是 iowait 主要来源 |
PRIO | IO 调度优先级(be/4 = best-effort 第4级) | 可用 ionice 调整 |
TID/COMMAND | 线程号 / 命令 | -P 切回进程聚合 |
四、典型排查
- top/iostat 见 iowait 高 →
sudo iotop -o一眼看出谁DISK WRITE/IO>最高。 IO>某进程接近 100% 但DISK READ/WRITE数值不大 → 它在做同步小 IO(每次都等落盘),吞吐不高但把时间全耗在等待上——正是 cpu_demo 场景2 那种"频繁小写 + 隐式刷盘"的模式。- 定位到进程后:
strace -e trace=write,fsync,read -p <PID>看具体在读写哪个文件、是否频繁 fsync。
五、关键指标速查
| 指标 | 缩写/英文 | 正常值 | 异常信号 |
|---|---|---|---|
| 磁盘读速率 | DISK READ / Disk Read | 视业务 | 突然暴涨 → 大量读盘 |
| 磁盘写速率 | DISK WRITE / Disk Write | 视业务 | 突然暴涨 + iowait 高 → 写瓶颈 |
| IO 等待占比 | IO> / IO Wait % | < 10% | 接近 100% → 进程几乎所有时间在等 IO |
| 换页读入 | SWAPIN / Swap In % | 0% | > 0 → 内存不足,该进程被换出页正在换回 |
| IO 优先级 | PRIO / IO Priority | be/4(默认) | rt → 实时 IO 优先级,可能饿死其他 IO |
六、常见排查方法与分析
6.1 定位 iowait 元凶
bash
top → %Cpu wa 高
→ iostat -x 1 → 确认哪块盘 await 高
→ sudo iotop -o → 直接看 DISK WRITE/READ 和 IO> 最高的进程
→ IO> 接近 100% 但吞吐不大 → 同步小 IO(每次都等落盘)
→ DISK WRITE 几十 MB/s 但 IO> 不高 → 大块顺序写(正常)6.2 IO> 高但吞吐量不大
现象:IO> 某进程 90%+,但 DISK READ/WRITE 只有几 KB/s。
根因:同步小 IO——频繁 write() + fsync(),每次等待落盘再发下一个。虽然每次数据量小,但等待时间全耗在"等落盘"上。
排查:
bash
strace -e trace=write,fsync -p <PID>
# 如果看到 write() → fsync() → write() → fsync()... 重复出现
# → 典型的小 IO + 隐式刷盘模式
# → 改成批量写 + 统一 fsync,或使用缓冲 IO6.3 某个进程在 swap
bash
sudo iotop -o → SWAPIN 列非零
→ 内存不足的证据
→ free -h 看 available
→ ps aux --sort=-%mem | head 找吃内存进程6.4 无 root 时的进程级 IO 定位
bash
pidstat -d 1 → 看 kB_rd/s, kB_wr/s, iodely
# 虽然没有 IO> 占比,但能看出谁在读写
# 结合 iostat -x 看设备级延迟七、交叉引用
- 设备级 IO:iostat(先确认哪块盘有问题再看进程)
- 进程级 IO(无 root):pidstat
-d(无 root 时的替代方案) - 系统调用定位:strace(看到具体在读写什么文件)
- IO 调度器:kernel-tuning §二(块设备队列/scheduler 调优)
- CPU iowait 入口:top
wa列
八、无 root / 容器受限时的替代
bash
pidstat -d 1 # sysstat 提供,普通用户即可看进程级 kB_rd/s、kB_wr/s(但无 IO> 等待占比)容器里 iotop 常因拿不到 taskstats 权限失败,需
--cap-add SYS_ADMIN或在宿主机上跑。
总结
iotop 把 iostat 的设备级 iowait 线索直接追到进程:经 taskstats netlink(需 root)给出每进程的读写速率、SWAPIN 和独有的 IO> 等待占比;典型判读是 IO> 接近 100% 但吞吐很小=同步小 IO+频繁 fsync,应改批量写,而无 root 时只能退回 pidstat -d。