工作中在解决IO问题的时候,主要搞清楚三个问题:
1、问题是否真的出现在IO?
2、哪个进程在大量使用IO
3、这个进程访问了哪些文件
通常我们在弄清楚第二个问题的时候,就已经知道IO是什么问题引起的了。
如果还不能,就继续弄清楚第三个问题,当我们知道进程访问了哪些文件后,就能反推程序中哪些地方使用了。
常见用于IO问题排查的命令有:
1、iotop
2、iostat
3、pidstat
4、strace
5、lsof、ps
一、磁盘性能指标
指标1: IOPS=r/s+w/s,即每秒读写次数;
指标2: 吞吐量=rkB/s+wkB/s,即每秒读写数据量;
指标3: 使用率,是指磁盘忙处理 I/O 请求的百分比。过高的使用率(比如超过 80%)通常意味着磁盘 I/O 存在性能瓶颈;
指标4: 响应时间,是指从发出 I/O 请求到收到响应的间隔时间;
二、IO问题排查思路
1、首先,查看系统IO情况,确认IO异常指标;(top/iostat)
2、其次,查看各进程IO使用情况,确认导致指标异常的进程;(iotop/pidstat)
3、最后,分析进程的IO行为(文件、磁盘读写),确认问题根源;(strace + ioprofile/lsof)
三、排查步骤
1、查看系统IO情况
说明:iostat和top命令中的iowait并不能等于IO负载情况,只是反映了CPU等待IO时间占用CPU总时间的百分比;使用iostat命令查看系统IO情况,如下:
iostat -xdm 1

await:IO请求平均响应时间(队列排队时间+IO处理时间),一般系统 I/O 响应时间应该低于 5ms,如果大于 10ms 就比较大了;
svctm:IO请求平均处理时间,不包含等待时间;
%util:磁盘繁忙程度。 例如,如果统计间隔 1 秒,该设备有 0.8 秒在处理 I/O,而 0.2 秒闲置,那么该设备的 %util = 0.8/1 = 80%;
avgqu-sz:IO请求的平均队列长度;
r/s + w/s 即为IOPS;
r MB/s + w MB/s 即为吞吐量;
r_await/w_await:读/写请求处理完成时间,等待时间+处理时间;
2、查看进程IO统计
iotop/pidstat命令可以查看系统中每个进程IO使用情况,利用这个信息可以找出占用IO最多的进程;
pidstat -d 1、iotop -o、pidstat -d 1 -p $(pgrep io_test) -l、iotop -p $(pgrep io_test)
3、分析进程IO行为
ioprofile可以统计出某个进程对每个文件的读写情况,本质上是 lsof + strace。对于Java应用,还可以使用jstack等命令工具查看线程行为;
lsof:查看文件打开情况
查看某个进程打开的所有文件: lsof -p <pid>
查看打开某个某个文件的所有进程: lsof <file>
strace:跟踪系统调用
#timeout:限制命令执行时间
timeout 5 strace -f -F -o <outputfile> -p <pid>
进程访问了哪些文件
要看进程访问哪些文件,可以用回我们之前排查系列文章里介绍的工具strace。
因为IO必定会产生文件相关的系统调用,我们可以用strace找到耗时长的读写操作。
然后就可以找到这些读写操作的fd,通过fd就能映射回磁盘上的文件了。
最后我们再根据文件来反推,是应用的什么地方会读写这些文件。
由于strace在之前的公众号文章里已经介绍过了,并且作者的懒癌再次发作,所以就直接略过吧。
总结