myfreax

如何查找高io等待的进程

什么是I/O等待?I/O 等待如何影响 Linux 服务器性能?我们如何监控和减少I/O等待的问题?继续阅读这些问题的答案

8 min read
By myfreax
如何查找高io等待的进程
linux 

IO等待或者iowaitwaitwa%iowait,或者wait%通常由Linux系统监控工具命令行显示。如top、sar、atop等。

就其本身而言,它是众多性能统计数据之一,可让我们深入了解Linux系统性能。当CPU负载峰值为60到80时。I/O等待会导致页面加载缓慢、超时和间歇性中断。

什么是I/O等待?I/O 等待如何影响 Linux 服务器性能?我们如何监控和减少I/O等待的问题?继续阅读这些问题的答案。

I/O等待适用于Unix和所有基于Unix的系统,包括macOS、FreeBSD、Solaris和Linux。

iowait等待是CPU或多个CPU空闲的时间百分比,在此期间系统有等待的磁盘I/O请求。

查找高io等待的进程

Linux用很多可用的工具可以用来发现排错,有些很容易使用,有些用法则比较高级。

查看I/O wait问题不仅需要使用一些高级工具,也需要一些基本工具的高级用法。I/O wait之所以难以排查是因为默认有太多的工具告诉你系统I/O阻塞。

但没那么多工具可以帮你缩小范围以便确定出是哪个或哪些进程引起的问题。

在排查IO等待问题上,首先确定是不是I/O引起系统缓慢。确定是不是I/O引起系统缓慢,你可以使用很多工具但最简单的还是unix命令top。

使用top命令即可看到类似这样的信息Cpu(s):  0.0%us,  0.5%sy,  0.0%ni, 99.5%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st

us用户空间占用CPU百分比。sy内核空间占用CPU百分比。ni用户进程空间内改变过优先级的进程占用CPU百分比。

id空闲CPU百分比。wa等待输入输出的CPU时间百分比。hi硬件中断。si软件中断。st实时。

[root@myfreax.com ~]# top
 top - 14:31:20 up 35 min, 4 users, load average: 2.25, 1.74, 1.68
 Tasks: 71 total, 1 running, 70 sleeping, 0 stopped, 0 zombie
 Cpu(s): 2.3%us, 1.7%sy, 0.0%ni, 0.0%id, 96.0%wa, 0.0%hi, 0.0%si, 0.0%st
 Mem: 245440k total, 241004k used, 4436k free, 496k buffers
 Swap: 409596k total, 5436k used, 404160k free, 182812k cached

‌‌‌‌从CPU(s) 这行你可以看出当前CPU I/O Wait的情况;越高的wa表示越多的cpu资源在等待I/O。其中用户、系统、空闲和wa等待值的总和应为100%。

上面的top命令从系统面大体展示了I/O Wait,但它没有告诉你哪个硬盘正在被影响;为此我们需要使用iostat命令。

[root@myfreax.com ~]# iostat -x 2 5
 avg-cpu: %user %nice %system %iowait %steal %idle
  3.66 0.00 47.64 48.69 0.00 0.00

 Device: rrqm/s wrqm/s r/s w/s rkB/s wkB/s avgrq-sz avgqu-sz await r_await w_await svctm %util
 sda 44.50 39.27 117.28 29.32 11220.94 13126.70 332.17 65.77 462.79 9.80 2274.71 7.60 111.41
 dm-0 0.00 0.00 83.25 9.95 10515.18 4295.29 317.84 57.01 648.54 16.73 5935.79 11.48 107.02
 dm-1 0.00 0.00 57.07 40.84 228.27 163.35 8.00 93.84 979.61 13.94 2329.08 10.93 107.02

iostat -x 2 5命令将每2秒打印出报告,共打印5次。-x选项告诉iostata打印出更详尽的报告。

iostat打印出的第1个报告,数值是基于最后一次系统启动的时间统计的。基于这个原因,在大部份情况下,iostat打印出的第1个报告应该被忽略。

每个子报告都是基于上1次的报告。在这个例子中,我们的命令将打印5次报告,第2份报告就是从第1份报告开始后的硬盘数据,第3份报告基于第2份,依此类推。

上述示例,sda盘的%utilized达到了111.41%。这表示引起I/O慢的进程在写入sda盘。

因为我这个测试实例中只有1个硬盘,但对于有多硬盘的服务器来说,这可以缩小在使用I/O的进程范围。

除了iostat的%utilized能提供丰富的信息外,像rrqm/s、wrqm/s这些每秒读、写的请求数,r/s、w/s每秒读写数也很有用。

查找引起高I/O的进程

[root@myfreax.com ~]# iotop
 Total DISK READ: 8.00 M/s | Total DISK WRITE: 20.36 M/s
  TID PRIO USER DISK READ DISK WRITE SWAPIN IO> COMMAND
 15758 be/4 root 7.99 M/s 8.01 M/s 0.00 % 61.97 % bonnie++ -n 0 -u 0 -r 239 -s 478 -f -b -d /tmp

查看哪个进程使用硬盘最多的最简单的方法就是使用iotop命令。通过查看数据,我们很容易就能确定是bonnie++这个进程引起我们机器高I/O。

虽然iotop好用,但默认主流的Linux发行版中是没有安装的。并且我个人也不推荐依赖默认系统没有安装的命令。

系统管理员总是会碰到这样的情况,他们没办法在短时间内简单地安装这些非默认包。

如果iotop没办法用,以下的步聚还是可以帮助你缩小这些进程的范围。

ps命令能打印出内存,cpu的情况。但没办法打印出硬盘I/O的情况。虽然ps没办法打印出I/O的情况,但它可以显示出进程是否在等待I/O。

ps的STAT状态列提供了进程当前的状态,以下是进程可能的状态。

D表示不间断睡眠。R在队列中运行。S可中断的睡眠,正在等待事件的完成。
T已经停止。

X表示进程已经死亡,你可能永远不会看到的状态。 Z表示已失效,通常称为僵尸进程,已终止但未由其父进程回收。

等待I/O的进程通常处于D状态,通过给出这些信息我们就可以简单的查找出处在wait状态的进程。

[root@myfreax.com ~]# for x in `seq 1 1 10`; do ps -eo state,pid,cmd | grep "^D"; echo "----"; sleep 5; done
 D 248 [jbd2/dm-0-8]
 D 16528 bonnie++ -n 0 -u 0 -r 239 -s 478 -f -b -d /tmp

命令会每5秒循环打印处于D状态的进程,共打印10次。从上面的输出可以看出bonnie++,pid 16528比其它进程更加占用I/O。

从这点,bonnie++看起来更有可能引起I/O Wait。但仅凭进程处于D状态,还不能完全确定就是这引起的I/O wait。

为了帮助肯定我们的怀疑,我们可以使用/proc文件系统。在这个进程目录里,每个进程都有一个io文件,里面的数值跟iotop命令获取的I/O数值一样。

[root@myfreax.com ~]# cat /proc/16528/io

注意16528是进程id。read_bytes和write_bytes就这个进程读写硬盘的字节数。在这里,bonnie++已经读取了46MB,写入524MB的数据。

查找写入频繁写入的文件

lsof命令会为你展示指定进程打开的所有文件。从这个列表,人们可以根据文件的大小和/proc io文件里出现的次数做出有用的猜测,哪个文件正在被频繁地写入。

为了减少输出的内容,我们可以使用-p选项来只打印指定进程id打开的文件。

 lsof -p 16528

减少I/O等待

优化应用程序的代码和数据库查询。这可以大大降低磁盘读/写的频率。这应该是您的第一种方法,因为您的应用程序效率越高,您在硬件上的长期支出就越少。

使您的Linux系统和软件版本保持最新。这不仅对安全性更好,而且通常情况下,最新支持的版本提供了显着的性能改进,无论是Nginx、Node.js、PHP、Python还是 MySQL。

确保您有足够的可用内存,以便大约一半的服务器内存用于内存缓冲区和缓存,而不是使用交换空间和分页到磁盘。

调整您的系统、存储设备和 Linux 内核以提高存储性能和使用寿命。最后,如果一切都失败了:将存储设备升级到更快的SSD、NVMe或其他高吞吐量存储设备。