写在前面
今天是 2018 年 01 月 04 号,已经是 2018 年的第四天了,最近这几天一直在做年终总结,回顾自己整年的工作,成长,问题,计划新的一年。2017年对于我来说,”tough year”!发生了太多的事,太多太多的事,开心的,烦恼的,2017年初计划的事情没有一件让我自己满意,想想嘘嘘不已!
这几天好好的写一篇总结!2018年对我来说,很重要!
回顾一下
上一篇文章 CPU.IOWAIT 偏高问题中其实已经大致分析出了问题所在。
文中『Find The Murderer』章节也指出了可能造成 IOWAIT% 偏高的进程,但不够有说服力。故此文尝试进一步的分析造成 IOWAIT% 偏高的原因!
查找最耗 IOWAIT 的进程
造成 IOWAIT% 偏高的进程一定也是 I/O 操作比较频繁的进程,CPU.IOWAIT 偏高问题中使用了两种方法,第一种是使用 ps 命令查找状态码为 ‘D’ 的进程,这种方式找到的结果不够准确;第二种是使用 iotop 工具,这种方式可能存在的问题是机器内核版本定制过,部分模块可能没有,而 iotop 这个工具要求内核版本相对较高,虽然我做了一点修改,骗过了 iotop,让 iotop 能正常运行,但总之得到的结果可能不够准确。
基于以上的分析,有必要用另外的方法。那么如何统计每个进程的 I/O 数呢,进而找到 I/O 数最高的进程?下面是查找过程。
首先,关闭syslog:
1 | dmesg -c |
接着下载一个 perl 脚本:
1 | wget https://github.com/true/aspersa-mirror/blob/master/iodump |
然后,打开 block_dump,这是内核关于 I/O 信息的一些日志:
1 | echo 1 > /proc/sys/vm/block_dump |
block_dump中设置非零值能够打开内核关于每一个 I/O 操作进行记录的开关,这时候可以看到内核已经收集到了 I/O 的日志:
1 | [root@localhost]# dmesg |
接下来就是对这些日志进行分析,这时就用到了 iodump 脚本:
1 | while true; do sleep 1; dmesg -c; done | perl iodump |
这时候可能会出错:
1 | -bash: perl: command not found |
oho,这台机器没有 perl 环境,好吧,接着装一个好了:
1 | wget http://www.cpan.org/src/5.0/perl-5.26.1.tar.gz |
然后添加环境变量:
1 | export PATH=$PATH:/root/mydir/localperl/bin |
重新执行命令:
1 | while true; do sleep 1; dmesg -c; done | perl iodump |
又抛错了?纳尼?
1 | Can't locate strict.pm in @INC (you may need to install the strict module) (@INC contains: /root/mydir/localperl/lib/site_perl/5.20.1/x86_64-linux /root/mydir/localperl/lib/site_perl/5.20.1 /root/mydir/localperl/lib/5.20.1/x86_64-linux /root/mydir/localperl/lib/5.20.1 .) at iodump line 34. |
好吧,设置下库路径:
1 | export PERL5LIB=$PERL5LIB:/root/mydir/localperl/lib |
重新运行命令,正常的话可以看到下面的输出:
1 | [root@localhost]# while true; do sleep 1; dmesg -c; done | ./localperl/bin/perl iodump |
统计结果很明白了,I/O 频繁的进程自然是导致 IOWAIT% 偏高的原因,那么根本原因还是硬件性能不足,磁盘 SSD 性能退化问题。
告一段落
CPU.IOWAIT 偏高问题以及本篇文章,做了很多关于 I/O、CPU、磁盘的比较细的研究,这些手段和方法值得以后排查其他问题借鉴!