linux如何快速定位 IO高进程

1. 快速定位 IO 高的进程

Linux 中排查磁盘 IO高

1
2
3
4
5
6
7
系统IO是否繁忙(wait)

哪个磁盘繁忙(pidstat)

哪个进程在读写(pidstat)

哪个文件被频繁访问(lsof)

2. 查看系统整体 IO

2.1 iostat

安装:

1
2
3
4
5
# CentOS/RHEL
yum install -y sysstat

# Debian/Ubuntu
apt install -y sysstat

查看:

1
iostat -x 1

重点关注:

1
2
3
4
5
6
7
%util      磁盘利用率
await IO等待时间(ms)
svctm 服务时间
r/s 每秒读次数
w/s 每秒写次数
rkB/s 读吞吐
wkB/s 写吞吐

例如:

1
2
Device    r/s    w/s   await  %util
sda 50 500 120 99.8

说明:

1
2
3
sda 已接近打满
写请求很多
IO延迟120ms较高

3. 查看哪个进程 IO 最高

3.1 iotop(最常用)

安装:

1
2
3
yum install -y iotop
# 或
apt install -y iotop

执行:

1
iotop

只看有IO的进程:

1
iotop -o

按累计排序:

1
iotop -ao

输出示例:

1
2
3
4
PID USER  DISK READ DISK WRITE COMMAND

1234 mysql 0.00 B/s 50.00 M/s mysqld
5678 nginx 20.00 M/s 0.00 B/s nginx

说明:

1
2
mysqld正在大量写盘
nginx正在大量读盘

3.2 pidstat

比 iotop 更适合服务器监控。

1
pidstat -d 1

输出:

1
2
3
PID   kB_rd/s  kB_wr/s Command
1234 0 51200 mysqld
5678 20480 0 nginx

持续观察:

1
pidstat -d 1 10

每秒统计一次,共10次。


4. 查看进程到底在访问哪个文件

4.1 lsof

查看进程打开文件:

1
lsof -p 1234

例如:

1
2
mysqld 1234 mysql REG /data/mysql/ibdata1
mysqld 1234 mysql REG /data/mysql/binlog.000123

4.2 lsof + grep deleted

经常用于排查磁盘空间不释放:

1
lsof | grep deleted

例如:

1
java 1234 logfile.log (deleted)

说明:

1
2
3
日志文件被删除
进程仍持有FD
空间不会释放

5. 查看块设备层面的 IO 来源

现代 Linux 推荐:

1
pidstat -d

或者:

1
sar -d 1

如果需要更底层分析:

1
blktrace
1
blktrace -d /dev/sda

配合:

1
blkparse

查看具体IO请求来源。


6. eBPF方式(生产环境推荐)

如果内核较新(4.x+)安装 BCC:

1
yum install bcc-tools

查看IO热点进程

1
biotop

输出:

1
2
PID   COMM      DISK_READ   DISK_WRITE
1234 mysqld 100MB/s 500MB/s

查看IO延迟

1
biolatency

查看文件热点

1
fileslower

查看慢文件IO:

1
fileslower 10

显示超过10ms的文件操作。


7. 最实用排查命令

日常线上排查,通常这几个就够了:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 查看IO等待
vmstat 1

# 查看磁盘
iostat -x 1

# 查看高IO进程
iotop -o

# 查看进程读写速率
pidstat -d 1

# 查看进程访问文件
lsof -p PID

# 查看进程累计IO
cat /proc/PID/io