Linux 系统监控、诊断工具之 IO wait

Linux 系统监控、诊断工具之 IO wait

1、问题:

最近在做日志的实时同步,上线之前是做过单份线上日志压力测试的,消息队列和客户端、本机都没问题,但是没想到上了第二份日志之后,问题来了:

集群中的某台机器 top 看到负载巨高,集群中的机器硬件配置一样,部署的软件都一样,却单单这一台负载有问题,初步猜测可能硬件有问题了。

同时,我们还需要把负载有异常的罪魁祸首揪出来,到时候从软件、硬件层面分别寻找解决方案。

2、排查:

从 top 中可以看到 load average 偏高,%wa 很高,%us 偏低:

从上图我们大致可以推断 IO 遇到了瓶颈,下面我们可以再用相关的 IO 诊断工具,具体的验证排查下。

PS:如果你对 top 的用法不了解,请参考我去年写的一篇博文:linux 系统监控、诊断工具之 top 详解

常用组合方式有如下几种:

  • 用vmstat、sar、iostat检测是否是CPU瓶颈
  • 用free、vmstat检测是否是内存瓶颈
  • 用iostat、dmesg 检测是否是磁盘I/O瓶颈
  • 用netstat检测是否是网络带宽瓶颈

2.1 vmstat

vmstat命令的含义为显示虚拟内存状态(“Virtual Memor Statics”),但是它可以报告关于进程、内存、I/O等系统整体运行状态。


它的相关字段说明如下:

Procs(进程)

  • r: 运行队列中进程数量,这个值也可以判断是否需要增加CPU。(长期大于1)
  • b: 等待IO的进程数量,也就是处在非中断睡眠状态的进程数,展示了正在执行和等待CPU资源的任务个数。当这个值超过了CPU数目,就会出现CPU瓶颈了

Memory(内存)

  • swpd: 使用虚拟内存大小,如果swpd的值不为0,但是SI,SO的值长期为0,这种情况不会影响系统性能。
  • free: 空闲物理内存大小。
  • buff: 用作缓冲的内存大小。
  • cache: 用作缓存的内存大小,如果cache的值大的时候,说明cache处的文件数多,如果频繁访问到的文件都能被cache处,那么磁盘的读IO bi会非常小。

Swap(交换区)

  • si: 每秒从交换区写到内存的大小,由磁盘调入内存。
  • so: 每秒写入交换区的内存大小,由内存调入磁盘。

注意:内存够用的时候,这2个值都是0,如果这2个值长期大于0时,系统性能会受到影响,磁盘IO和CPU资源都会被消耗。有些朋友看到空闲内存(free)很少的或接近于0时,就认为内存不够用了,不能光看这一点,还要结合si和so,如果free很少,但是si和so也很少(大多时候是0),那么不用担心,系统性能这时不会受到影响的。

IO(输入输出)

(现在的Linux版本块的大小为1kb)

  • bi: 每秒读取的块数
  • bo: 每秒写入的块数

注意:随机磁盘读写的时候,这2个值越大(如超出1024k),能看到CPU在IO等待的值也会越大。

system(系统)

  • in: 每秒中断数,包括时钟中断。
  • cs: 每秒上下文切换数。

注意:上面2个值越大,会看到由内核消耗的CPU时间会越大。

CPU

(以百分比表示)

  • us: 用户进程执行时间百分比(user time)。us的值比较高时,说明用户进程消耗的CPU时间多,但是如果长期超50%的使用,那么我们就该考虑优化程序算法或者进行加速。
  • sy: 内核系统进程执行时间百分比(system time)。sy的值高时,说明系统内核消耗的CPU资源多,这并不是良性表现,我们应该检查原因。
  • wa: IO等待时间百分比。wa的值高时,说明IO等待比较严重,这可能由于磁盘大量作随机访问造成,也有可能磁盘出现瓶颈(块操作)。
  • id: 空闲时间百分比

从 vmstat 中可以看到,CPU大部分的时间浪费在等待IO上面,可能是由于大量的磁盘随机访问或者磁盘的带宽所造成的,bi、bo 也都超过 1024k,应该是遇到了IO瓶颈。

2.2 iostat

下面再用更加专业的磁盘 IO 诊断工具来看下相关统计数据。


它的相关字段说明如下:

  • rrqm/s: 每秒进行 merge 的读操作数目。即 delta(rmerge)/s
  • wrqm/s: 每秒进行 merge 的写操作数目。即 delta(wmerge)/s
  • r/s: 每秒完成的读 I/O 设备次数。即 delta(rio)/s
  • w/s: 每秒完成的写 I/O 设备次数。即 delta(wio)/s
  • rsec/s: 每秒读扇区数。即 delta(rsect)/s
  • wsec/s: 每秒写扇区数。即 delta(wsect)/s
  • rkB/s: 每秒读K字节数。是 rsect/s 的一半,因为每扇区大小为512字节。(需要计算)
  • wkB/s: 每秒写K字节数。是 wsect/s 的一半。(需要计算)
  • avgrq-sz: 平均每次设备I/O操作的数据大小 (扇区)。delta(rsect+wsect)/delta(rio+wio)
  • avgqu-sz: 平均I/O队列长度。即 delta(aveq)/s/1000 (因为aveq的单位为毫秒)。
  • await: 平均每次设备I/O操作的等待时间 (毫秒)。即 delta(ruse+wuse)/delta(rio+wio)
  • svctm: 平均每次设备I/O操作的服务时间 (毫秒)。即 delta(use)/delta(rio+wio)
  • %util: 一秒中有百分之多少的时间用于 I/O 操作,或者说一秒中有多少时间 I/O 队列是非空的。即 delta(use)/s/1000 (因为use的单位为毫秒)

可以看到两块硬盘中的 sdb 的利用率已经 100%,存在严重的 IO 瓶颈,下一步我们就是要找出哪个进程在往这块硬盘读写数据。

2.3 iotop

根据 iotop 的结果,我们迅速的定位到是 flume 进程的问题,造成了大量的 IO wait。

但是在开头我已经说了,集群中的机器配置一样,部署的程序也都 rsync 过去的一模一样,难道是硬盘坏了?

这得找运维同学来查证了,最后的结论是:

Sdb为双盘raid1,使用raid卡为“LSI Logic / Symbios Logic SAS1068E”,无cache。近400的IOPS压力已经达到了硬件极限。而其它机器使用的raid卡是“LSI Logic / Symbios Logic MegaRAID SAS 1078”,有256MB cache,并未达到硬件瓶颈,解决办法是更换能提供更大IOPS的机器,比如最后我们换了一台带 PERC6/i 集成RAID控制器卡的机器。需要说明的是,raid信息是在raid卡和磁盘固件里面各存一份,磁盘上的raid信息和raid卡上面的信息格式要是匹配的,否则raid卡识别不了就需要格式化磁盘。

IOPS本质上取决于磁盘本身,但是又很多提升IOPS的方法,加硬件cache、采用RAID阵列是常用的办法。如果是DB那种IOPS很高的场景,现在流行用SSD来取代传统的机械硬盘。

不过前面也说了,我们从软硬件两方面着手的目的就是看能否分别寻求代价最小的解决方案:

知道硬件的原因了,我们可以尝试把读写操作移到另一块盘,然后再看看效果: 

3、最后的话:另辟蹊径

其实,除了用上述专业的工具定位这个问题外,我们可以直接利用进程状态来找到相关的进程。

我们知道进程有如下几种状态:

  • D uninterruptible sleep (usually IO)
  • R running or runnable (on run queue)
  • S interruptible sleep (waiting for an event to complete)
  • T stopped, either by a job control signal or because it is being traced.
  • W paging (not valid since the 2.6.xx kernel)
  • X dead (should never be seen)
  • Z defunct ("zombie") process, terminated but not reaped by its parent.

其中状态为 D 的一般就是由于 wait IO 而造成所谓的”非中断睡眠“,我们可以从这点入手然后一步步的定位问题:


  1. # for x in `seq 10`; do ps -eo state,pid,cmd | grep "^D"; echo "----"; sleep 5; done
  2. D 248 [jbd2/dm-0-8]
  3. D 16528 bonnie++ -n 0 -u 0 -r 239 -s 478 -f -b -d /tmp
  4. ----
  5. D 22 [kdmflush]
  6. D 16528 bonnie++ -n 0 -u 0 -r 239 -s 478 -f -b -d /tmp
  7. ----
  8. # 或者:
  9. # while true; do date; ps auxf | awk '{if($8=="D") print $0;}'; sleep 1; done
  10. Tue Aug 23 20:03:54 CLT 2011
  11. root 302 0.0 0.0 0 0 ? D May22 2:58 \_ [kdmflush]
  12. root 321 0.0 0.0 0 0 ? D May22 4:11 \_ [jbd2/dm-0-8]
  13. Tue Aug 23 20:03:55 CLT 2011
  14. Tue Aug 23 20:03:56 CLT 2011
  15. # cat /proc/16528/io
  16. rchar: 48752567
  17. wchar: 549961789
  18. syscr: 5967
  19. syscw: 67138
  20. read_bytes: 49020928
  21. write_bytes: 549961728
  22. cancelled_write_bytes: 0
  23. # lsof -p 16528
  24. COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
  25. bonnie++ 16528 root cwd DIR 252,0 4096 130597 /tmp
  26. <truncated>
  27. bonnie++ 16528 root 8u REG 252,0 501219328 131869 /tmp/Bonnie.16528
  28. bonnie++ 16528 root 9u REG 252,0 501219328 131869 /tmp/Bonnie.16528
  29. bonnie++ 16528 root 10u REG 252,0 501219328 131869 /tmp/Bonnie.16528
  30. bonnie++ 16528 root 11u REG 252,0 501219328 131869 /tmp/Bonnie.16528
  31. bonnie++ 16528 root 12u REG 252,0 501219328 131869 <strong>/tmp/Bonnie.16528</strong>
  32. # df /tmp
  33. Filesystem 1K-blocks Used Available Use% Mounted on
  34. /dev/mapper/workstation-root 7667140 2628608 4653920 37% /
  35. # fuser -vm /tmp
  36. USER PID ACCESS COMMAND
  37. /tmp: db2fenc1 1067 ....m db2fmp
  38. db2fenc1 1071 ....m db2fmp
  39. db2fenc1 2560 ....m db2fmp
  40. db2fenc1 5221 ....m db2fmp

原文发布时间:2014-12-16

本文来自云栖合作伙伴“linux中国”

时间: 2024-08-30 20:21:29

Linux 系统监控、诊断工具之 IO wait的相关文章

Linux系统监控常用命令

1.PID.TID的区分 uid是user id,即用户id,root用户的uid是0,0为最高权限, gid是group id,用户组id,使用 id 命令可以很简单的通过用户名查看UID.GID:~$ id bingyueuid=1000(bingyue) gid=1000(bingyue) groups=1000(bingyue)~$ id rootuid=0(root) gid=0(root) groups=0(root) pid是process id,即进程id,可以通过pid找到这个

Linux系统中使用iostat分析IO性能

对于I/O-bond类型的进程,我们经常用iostat工具查看进程IO请求下发的数量.系统处理IO请求的耗时,进而分析进程与操作系统的交互过程中IO方面是否存在瓶颈. 下面通过iostat命令使用实例,说明使用iostat查看IO请求下发情况.系统IO处理能力的方法,以及命令执行结果中各字段的含义. 1.不加选项执行iostat 我们先来看直接执行iostat的输出结果: linux # iostat Linux 2.6.16.60-0.21-smp (linux) 06/12/12 avg-c

Linux系统监控、诊断工具之top命令详解

接触 linux 的人对于 top 命令可能不会陌生(不同系统名字可能不一样,如 IBM 的 aix 中叫 topas ),它的作用主要用来监控系统实时负载率.进程的资源占用率及其它各项系统状态属性是否正常. 下面我们先来看张 top 命令的截图: &lt;img class="aligncenter wp-image-4998" src="http://zhangge.net/wp-content/uploads/2015/01/top1.jpg?width=480

常用的linux系统监控命令整理

  找到最耗CPU的java线程ps命令 命令:ps -mp pid -o THREAD,tid,time 或者 ps -Lfp pid 结果展示: 这个命令的作用,主要是可以获取到对应一个进程下的线程的一些信息. 比如你想分析一下一个java进程的一些运行瓶颈点,可以通过该命令找到所有当前Thread的占用CPU的时间,也就是这里的最后一列. 比如这里找到了一个TID : 30834 ,所占用的TIME时间最高. 通过 printf "%xn" 30834 首先转化成16进制, 继续

Linux系统监控神器--Collectl

系统资源监控 为使系统良好运转,Linux系统管理员经常需要监测cpu,内存,磁盘,网络等系统信息.Linux上已有iotop,top,free,htop,sar等丰富的常规工具来实现监测功能.今天让我们走进Collectl来了解这个集测试/监控/分析系统性能为一体的Linux工具. Collectl作为一个轻量级的监控工具,在同类工具中是功能最全的.用户可监测不同的复杂系统矩阵值,并可保留数据以做之后的分析.不同于其他只用来监测特定系统参数的工具,Collectl可以同时监测不同的变量,并以合

[网络摘录学习]常用的Linux系统监控命令

发现这篇文章可工作性能调优使用,摘录于下.原文链接:http://os.51cto.com/art/201108/286625.htm版权归原作者所有. 找到最耗CPU的java线程 ps命令 命令: ps -mp pid -o THREAD,tid,time 或者 ps -Lfp pid 结果展示:     这个命令的作用,主要是可以获取到对应一个进程下的线程的一些信息. 比如你想分析一下一个java进程的一些运行瓶颈点,可以通过该命令找到所有当前Thread的占用CPU的时间,也就是这里的最

打造自己的Linux服务器监控小工具

周末在家蛮无聊的,思考人生的同时突发奇想就写一个服务器监控的小工具吧.学JAVA快1年了,刚好检验一下自己! 仔细想想呢估计作用可能也有限,毕竟外面各种监控工具也很多,初衷其实也只是练练手,加上平时比较懒,那么为了更方便的看服务器性能指标,所以就选了这个题材咯,那么就开始吧. 不过优点也是有的嘛,至少不需要在服务器端装一个脚本之类的了. 一.小工具的功能 1 能够读取服务器CPU,IO,Memory的性能指标并在页面展示出来 2 把监控的信息打印到文件,方便进行数据分析 二.准备工作 java开

常用的linux系统监控命令

记录一下自己常用的linux系统命令,方便以后查阅,发觉记忆越来越不行了 找到最耗CPU的java线程 ps命令 命令:ps -mp pid -o THREAD,tid,time   或者  ps -Lfp pid 结果展示:   这个命令的作用,主要是可以获取到对应一个进程下的线程的一些信息. 比如你想分析一下一个java进程的一些运行瓶颈点,可以通过该命令找到所有当前Thread的占用CPU的时间,也就是这里的最后一列.   比如这里找到了一个TID : 30834 ,所占用的TIME时间最

Linux系统中vim工具常用命令大全

  在linux下做开发,甚至是只做管理维护工作,也少不了Vim的使用.作为一个新手,我也是刚刚接触,本节将我日常使用或收集的Vim常用命令记录下来. 当然,直接在命令行上输入:vimtutor,就可以学习到Vim的所有命令了.Vim很强大,很多牛人在vim里集成很多插件什么的,但这里只介绍基本vim命令. 移动命令 h "左j "下k "上l "右w "光标移动到下一个单词的首字符 a word forwardb "光标移动到上一个单词的首字符