zrenpro 2012-03-15
命令总结:
1.top/vmstat发现wa%过高,vmstatb>1;
参考文章:
1.关于Linux系统指令top之%wa占用高,用`iostat`探个究竟
最近测试一项目,性能非常不理想。老版本逻辑和功能都简单时,性能是相当的好!接口点击率是万级的。谁知修改后上不了百。
架设Jboss服务器,业务逻辑用Java处理,核心模块使用C++处理,使用JNI衔接。
本应用对CPU和硬盘第三非常敏感,因为有压缩解压和大量数据交互。起初作压力测试时,发现服务器各资源使用都有剩余,而点击率曲线波动却非常大,简单看似乎是应用程序有问题。[点击图片可在新窗口打开]
使用top查看Cpu各核的使用情况,发现一个非常诡异的现象:
1.经常只有部分核是满载的,另外一部分基本空闲;
2.在CPU满载时,%wa的波动比较大,有时会占到较大比例。
所以,监控整个CPU时会发现CPU使用率不高,实际上任务总是分派到某个核上且导致对应核满载。无法有效使用CPU,其它资源自然也难以有效调度。
废话不多说,%wa指CPU等待磁盘写入完成的时间。莫非是磁盘忙,怎样证明是磁盘在忙?
首先看下%wa的解释:PercentageoftimethattheCPUorCPUswereidleduringwhichthesystemhadanoutstandingdiskI/Orequest.
起初用`lsof|less`查看文件的读写情况,发现/tmp目录下有大量文件读写。经查证,是Jboss处理上传文件会默认写入到/tmp文件夹,然后再执行了一次拷贝到程序读取的目录。修改Jboss配置直接写入到程序读写目录,性能没有本质上的改变。[点击图片可在新窗口打开]
关于CPU使用波动大,我们也在程序内部加了很多计时器,发现某些模块在处理并发时会有响应时间很长的情况,这点证实了为什么点击率波动很大。
但此模块进行单进程串行测试时,每秒完成事务数是相当可观的。一个进程每秒完成的事务数都比当前测试点击率要高很多!使用多进程来测试此模块时,发现“进程数=核数”时效果最佳。于是在Java层控制同时进入此模块的数量,毕竟Java是调用JNI来使用此模块,使用全局锁来控制并发,最终结果没有想象的那么理想,但明显可以看出:通过控制并发数,能有效提高CPU的使用率,点击率也上升了一些。[点击图片可在新窗口打开]
另外一个问题就是,CPU会出现一会满载,一会空闲的情况,导致点击率曲线仍然波动大的问题。商讨后决定在C++代码中加入“释放CPU控制权”的逻辑,这样就在代码层来作了一个负载均衡。点击率波动的问题得到了好转,但点击率仍然不理想,预期瓶颈是网络而实际变成了CPU。
优化了压缩解决的处理后,性能没有明显提升。这时我才想起%wa,我还没有进一步证明是磁盘的闲忙程度。使用了一些监控工具,诸如:vmstat、sar、dstat、sysstat没有发现对磁盘作非常详细的监控。最后试了下iostat,搞定![点击图片可在新窗口打开]
iostat的编译非常简单,就一个c文件,MakeFile里作者写了一句话“Cann'tbesimpler”。直接makeinstall就在目录下生成了iostat的可执行文件,看一下帮助,执行`iostat-cdDx10`。其中有一列“%b”描述了磁盘的闲忙程序,简单直接。另外还有详细的磁盘IO读写数据,帮助里也解释得非常清楚。
再进行一次压力测试,拿着这份数据,已经绝对性的说明问题了。此时那些大牛把代码改了一下,性能立马就上去了,千兆网络直接成为系统瓶颈。并于Java的控制问题,改用Apache直接编译程序模块调用,完成变为可控,问题瞬间解决![点击图片可在新窗口打开]
附上iostat的源码:
http://code.google.com/p/tester-higkoo/source/browse/trunk/Tools/iostat/iostat.c
转自:http://hi.baidu.com/higkoo/blog/item/d4f7f822e7871cf8d6cae25e.html
2.iostat来对linux硬盘IO性能进行了解
以前一直不太会用这个参数。现在认真研究了一下iostat,因为刚好有台重要的服务器压力高,所以放上来分析一下.下面这台就是IO有压力过大的服务器
#iostat-x110
Linux2.6.18-92.el5xen02/03/2009
avg-cpu:%user%nice%system%iowait%steal%idle
1.100.004.8239.540.0754.46
Device:rrqm/swrqm/sr/sw/srsec/swsec/savgrq-szavgqu-szawaitsvctm%util
sda0.003.500.402.505.6048.0018.480.000.970.970.28
sdb0.000.000.000.000.000.000.000.000.000.000.00
sdc0.000.000.000.000.000.000.000.000.000.000.00
sdd0.000.000.000.000.000.000.000.000.000.000.00
sde0.000.100.300.202.402.409.600.001.601.600.08
sdf17.400.50102.000.2012095.205.60118.400.706.812.0921.36
sdg232.401.90379.700.5076451.2019.20201.134.9413.782.4593.16
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的单位为毫秒)
如果%util接近100%,说明产生的I/O请求太多,I/O系统已经满负荷,该磁盘
可能存在瓶颈。
idle小于70%IO压力就较大了,一般读取速度有较多的wait.
同时可以结合vmstat查看查看b参数(等待资源的进程数)和wa参数(IO等待所占用的CPU时间的百分比,高过30%时IO压力高)
另外还可以参考
svctm一般要小于await(因为同时等待的请求的等待时间被重复计算了),svctm的大小一般和磁盘性能有关,CPU/内存的负荷也会对其有影响,请求过多也会间接导致svctm的增加。await的大小一般取决于服务时间(svctm)以及I/O队列的长度和I/O请求的发出模式。如果svctm比较接近await,说明I/O几乎没有等待时间;如果await远大于svctm,说明I/O队列太长,应用得到的响应时间变慢,如果响应时间超过了用户可以容许的范围,这时可以考虑更换更快的磁盘,调整内核elevator算法,优化应用,或者升级CPU。
队列长度(avgqu-sz)也可作为衡量系统I/O负荷的指标,但由于avgqu-sz是按照单位时间的平均值,所以不能反映瞬间的I/O洪水。
别人一个不错的例子.(I/O系统vs.超市排队)
举一个例子,我们在超市排队checkout时,怎么决定该去哪个交款台呢?首当是看排的队人数,5个人总比20人要快吧?除了数人头,我们也常常看看前面人购买的东西多少,如果前面有个采购了一星期食品的大妈,那么可以考虑换个队排了。还有就是收银员的速度了,如果碰上了连钱都点不清楚的新手,那就有的等了。另外,时机也很重要,可能5分钟前还人满为患的收款台,现在已是人去楼空,这时候交款可是很爽啊,当然,前提是那过去的5分钟里所做的事情比排队要有意义(不过我还没发现什么事情比排队还无聊的)。
I/O系统也和超市排队有很多类似之处:
r/s+w/s类似于交款人的总数
平均队列长度(avgqu-sz)类似于单位时间里平均排队人的个数
平均服务时间(svctm)类似于收银员的收款速度
平均等待时间(await)类似于平均每人的等待时间
平均I/O数据(avgrq-sz)类似于平均每人所买的东西多少
I/O操作率(%util)类似于收款台前有人排队的时间比例。
我们可以根据这些数据分析出I/O请求的模式,以及I/O的速度和响应时间。
下面是别人写的这个参数输出的分析
#iostat-x1
avg-cpu:%user%nice%sys%idle
16.240.004.3179.44
Device:rrqm/swrqm/sr/sw/srsec/swsec/srkB/swkB/savgrq-szavgqu-szawaitsvctm%util
/dev/cciss/c0d0
0.0044.901.0227.558.16579.594.08289.8020.5722.3578.215.0014.29
/dev/cciss/c0d0p1
0.0044.901.0227.558.16579.594.08289.8020.5722.3578.215.0014.29
/dev/cciss/c0d0p2
0.000.000.000.000.000.000.000.000.000.000.000.000.00
上面的iostat输出表明秒有28.57次设备I/O操作:总IO(io)/s=r/s(读)+w/s(写)=1.02+27.55=28.57(次/秒)其中写操作占了主体(w:r=27:1)。
平均每次设备I/O操作只需要5ms就可以完成,但每个I/O请求却需要等上78ms,为什么?因为发出的I/O请求太多(每秒钟约29个),假设这些请求是同时发出的,那么平均等待时间可以这样计算:
平均等待时间=单个I/O服务时间*(1+2+…+请求总数-1)/请求总数
应用到上面的例子:平均等待时间=5ms*(1+2+…+28)/29=70ms,和iostat给出的78ms的平均等待时间很接近。这反过来表明I/O是同时发起的。
每秒发出的I/O请求很多(约29个),平均队列却不长(只有2个左右),这表明这29个请求的到来并不均匀,大部分时间I/O是空闲的。
一秒中有14.29%的时间I/O队列中是有请求的,也就是说,85.71%的时间里I/O系统无事可做,所有29个I/O请求都在142毫秒之内处理掉了。
delta(ruse+wuse)/delta(io)=await=78.21=>delta(ruse+wuse)/s=78.21*delta(io)/s=78.21*28.57=2232.8,表明每秒内的I/O请求总共需要等待2232.8ms。所以平均队列长度应为2232.8ms/1000ms=2.23,而iostat给出的平均队列长度(avgqu-sz)却为22.35,为什么?!因为iostat中有bug,avgqu-sz值应为2.23,而不是22.35。
3.linuxlsof详解
lsof简介
lsof(listopenfiles)是一个列出当前系统打开文件的工具。在linux环境下,任何事物都以文件的形式存在,通过文件不仅仅可以访问常规数据,还可以访问网络连接和硬件。所以如传输控制协议(TCP)和用户数据报协议(UDP)套接字等,系统在后台都为该应用程序分配了一个文件描述符,无论这个文件的本质如何,该文件描述符为应用程序与基础操作系统之间的交互提供了通用接口。因为应用程序打开文件的描述符列表提供了大量关于这个应用程序本身的信息,因此通过lsof工具能够查看这个列表对系统监测以及排错将是很有帮助的。
lsof使用
lsof输出信息含义
在终端下输入lsof即可显示系统打开的文件,因为lsof需要访问核心内存和各种文件,所以必须以root用户的身份运行它才能够充分地发挥其功能。
COMMANDPIDUSERFDTYPEDEVICESIZENODENAMEinit1rootcwdDIR3,310242/init1rootrtdDIR3,310242/init1roottxtREG3,3384321763452/sbin/initinit1rootmemREG3,31061141091620/lib/libdl-2.6.soinit1rootmemREG3,375606961091614/lib/libc-2.6.soinit1rootmemREG3,3794601091669/lib/libselinux.so.1init1rootmemREG3,32232801091668/lib/libsepol.so.1init1rootmemREG3,35641361091607/lib/ld-2.6.soinit1root10uFIFO0,151309/dev/initctl
每行显示一个打开的文件,若不指定条件默认将显示所有进程打开的所有文件。lsof输出各列信息的意义如下:
COMMAND:进程的名称PID:进程标识符USER:进程所有者FD:文件描述符,应用程序通过文件描述符识别该文件。如cwd、txt等TYPE:文件类型,如DIR、REG等DEVICE:指定磁盘的名称SIZE:文件的大小NODE:索引节点(文件在磁盘上的标识)NAME:打开文件的确切名称
其中FD列中的文件描述符cwd值表示应用程序的当前工作目录,这是该应用程序启动的目录,除非它本身对这个目录进行更改。
txt类型的文件是程序代码,如应用程序二进制文件本身或共享库,如上列表中显示的/sbin/init程序。其次数值表示应用
程序的文件描述符,这是打开该文件时返回的一个整数。如上的最后一行文件/dev/initctl,其文件描述符为10。u表示该
文件被打开并处于读取/写入模式,而不是只读®或只写(w)模式。同时还有大写的W表示该应用程序具有对整个文件的写
锁。该文件描述符用于确保每次只能打开一个应用程序实例。初始打开每个应用程序时,都具有三个文件描述符,从0到2,
分别表示标准输入、输出和错误流。所以大多数应用程序所打开的文件的FD都是从3开始。
与FD列相比,Type列则比较直观。文件和目录分别称为REG和DIR。而CHR和BLK,分别表示字符和块设备;
或者UNIX、FIFO和IPv4,分别表示UNIX域套接字、先进先出(FIFO)队列和网际协议(IP)套接字。
lsof常用参数
lsof常见的用法是查找应用程序打开的文件的名称和数目。可用于查找出某个特定应用程序将日志数据记录到何处,或者正在跟踪某个问题。
例如,linux限制了进程能够打开文件的数目。通常这个数值很大,所以不会产生问题,并且在需要时,应用程序可以请求更大的值(直到某
个上限)。如果你怀疑应用程序耗尽了文件描述符,那么可以使用lsof统计打开的文件数目,以进行验证。lsof语法格式是:
lsof[options]filename
常用的参数列表:
lsoffilename显示打开指定文件的所有进程lsof-a表示两个参数都必须满足时才显示结果lsof-cstring显示COMMAND列中包含指定字符的进程所有打开的文件lsof-uusername显示所属user进程打开的文件lsof-ggid显示归属gid的进程情况lsof+d/DIR/显示目录下被进程打开的文件lsof+D/DIR/同上,但是会搜索目录下的所有目录,时间相对较长lsof-dFD显示指定文件描述符的进程lsof-n不将IP转换为hostname,缺省是不加上-n参数lsof-i用以显示符合条件的进程情况lsof-i[46][protocol][@hostname|hostaddr][:service|port]46-->IPv4orIPv6protocol-->TCPorUDPhostname-->Internethostnamehostaddr-->IPv4地址service-->/etc/service中的servicename(可以不只一个)port-->端口号(可以不只一个)
例如:查看22端口现在运行的情况
#lsof-i:22COMMANDPIDUSERFDTYPEDEVICESIZENODENAMEsshd1409root3uIPv65678TCP*:ssh(LISTEN)
查看所属root用户进程所打开的文件类型为txt的文件:
#lsof-a-uroot-dtxtCOMMANDPIDUSERFDTYPEDEVICESIZENODENAMEinit1roottxtREG3,3384321763452/sbin/initmingetty1632roottxtREG3,3143661763337/sbin/mingettymingetty1633roottxtREG3,3143661763337/sbin/mingettymingetty1634roottxtREG3,3143661763337/sbin/mingettymingetty1635roottxtREG3,3143661763337/sbin/mingettymingetty1636roottxtREG3,3143661763337/sbin/mingettymingetty1637roottxtREG3,3143661763337/sbin/mingettykdm1638roottxtREG3,31325481428194/usr/bin/kdmX1670roottxtREG3,317163961428336/usr/bin/Xorgkdm1671roottxtREG3,31325481428194/usr/bin/kdmstartkde2427roottxtREG3,36454081544195/bin/bash......
lsof使用实例
一、查找谁在使用文件系统
在卸载文件系统时,如果该文件系统中有任何打开的文件,操作通常将会失败。那么通过lsof可以找出那些进程在使用当前要卸载的文件系统,如下:
#lsof/GTES11/COMMANDPIDUSERFDTYPEDEVICESIZENODENAMEbash4208rootcwdDIR3,140962/GTES11/vim4230rootcwdDIR3,140962/GTES11/
在这个示例中,用户root正在其/GTES11目录中进行一些操作。一个bash是实例正在运行,并且它当前的目录为/GTES11,另一个则显示的是vim正在编辑/GTES11下的文件。要成功地卸载/GTES11,应该在通知用户以确保情况正常之后,中止这些进程。这个示例说明了应用程序的当前工作目录非常重要,因为它仍保持着文件资源,并且可以防止文件系统被卸载。这就是为什么大部分守护进程(后台进程)将它们的目录更改为根目录、或服务特定的目录(如sendmail示例中的/var/spool/mqueue)的原因,以避免该守护进程阻止卸载不相关的文件系统。
二、恢复删除的文件
当Linux计算机受到入侵时,常见的情况是日志文件被删除,以掩盖攻击者的踪迹。管理错误也可能导致意外删除重要的文件,比如在清理旧日志时,意外地删除了数据库的活动事务日志。有时可以通过lsof来恢复这些文件。
当进程打开了某个文件时,只要该进程保持打开该文件,即使将其删除,它依然存在于磁盘中。这意味着,进程并不知道文件已经被删除,它仍然可以向打开该文件时提供给它的文件描述符进行读取和写入。除了该进程之外,这个文件是不可见的,因为已经删除了其相应的目录索引节点。
在/proc目录下,其中包含了反映内核和进程树的各种文件。/proc目录挂载的是在内存中所映射的一块区域,所以这些文件和目录并不存在于磁盘中,因此当我们对这些文件进行读取和写入时,实际上是在从内存中获取相关信息。大多数与lsof相关的信息都存储于以进程的PID命名的目录中,即/proc/1234中包含的是PID为1234的进程的信息。每个进程目录中存在着各种文件,它们可以使得应用程序简单地了解进程的内存空间、文件描述符列表、指向磁盘上的文件的符号链接和其他系统信息。lsof程序使用该信息和其他关于内核内部状态的信息来产生其输出。所以lsof可以显示进程的文件描述符和相关的文件名等信息。也就是我们通过访问进程的文件描述符可以找到该文件的相关信息。
当系统中的某个文件被意外地删除了,只要这个时候系统中还有进程正在访问该文件,那么我们就可以通过lsof从/proc目录下恢复该文件的内容。假如由于误操作将/var/log/messages文件删除掉了,那么这时要将/var/log/messages文件恢复的方法如下:
首先使用lsof来查看当前是否有进程打开/var/logmessages文件,如下:
#lsof|grep/var/log/messagessyslogd1283root2wREG3,353810171773647/var/log/messages(deleted)
从上面的信息可以看到PID1283(syslogd)打开文件的文件描述符为2。同时还可以看到/var/log/messages已经标记被删除了。因此我们可以在/proc/1283/fd/2(fd下的每个以数字命名的文件表示进程对应的文件描述符)中查看相应的信息,如下:
#head-n10/proc/1283/fd/2Aug413:50:15holmes86syslogd1.4.1:restart.Aug413:50:15holmes86kernel:klogd1.4.1,logsource=/proc/kmsgstarted.Aug413:50:15holmes86kernel:Linuxversion2.6.22.1-8([email protected])(gccversion4.2.0)#1SMPWedJul1811:18:32EDT2007Aug413:50:15holmes86kernel:BIOS-providedphysicalRAMmap:Aug413:50:15holmes86kernel:BIOS-e820:0000000000000000-000000000009f000(usable)Aug413:50:15holmes86kernel:BIOS-e820:000000000009f000-00000000000a0000(reserved)Aug413:50:15holmes86kernel:BIOS-e820:0000000000100000-000000001f7d3800(usable)Aug413:50:15holmes86kernel:BIOS-e820:000000001f7d3800-0000000020000000(reserved)Aug413:50:15holmes86kernel:BIOS-e820:00000000e0000000-00000000f0007000(reserved)Aug413:50:15holmes86kernel:BIOS-e820:00000000f0008000-00000000f000c000(reserved)
从上面的信息可以看出,查看/proc/8663/fd/15就可以得到所要恢复的数据。如果可以通过文件描述符查看相应的数据,那么就可以使用I/O重定向将其复制到文件中,如:
cat/proc/1283/fd/2>/var/log/messages
对于许多应用程序,尤其是日志文件和数据库,这种恢复删除文件的方法非常有用。
4.Linuxiostat监测IO状态[转]
Linux系统出现了性能问题,一般我们可以通过top、iostat、free、vmstat等命令来查看初步定位问题。其中iostat可以给我们提供丰富的IO状态数据。
1.基本使用
$iostat-d-k110
参数-d表示,显示设备(磁盘)使用状态;-k某些使用block为单位的列强制使用Kilobytes为单位;110表示,数据显示每隔1秒刷新一次,共显示10次。
$iostat-d-k110
Device:tpskB_read/skB_wrtn/skB_readkB_wrtn
sda39.2921.141.4444133980729990031
sda10.000.000.001623523
sda21.321.434.542983427394827104
sda36.300.8524.9517816289520725244
sda50.850.463.40954350370970116
sda60.000.000.00550236
sda70.000.000.004060
sda80.000.000.004060
sda90.000.000.004060
sda1060.6818.3571.433830022631490928140
Device:tpskB_read/skB_wrtn/skB_readkB_wrtn
sda327.555159.18102.045056100
sda10.000.000.0000
tps:该设备每秒的传输次数(Indicatethenumberoftransferspersecondthatwereissuedtothedevice.)。“一次传输”意思是“一次I/O请求”。多个逻辑请求可能会被合并为“一次I/O请求”。“一次传输”请求的大小是未知的。
kB_read/s:每秒从设备(driveexpressed)读取的数据量;kB_wrtn/s:每秒向设备(driveexpressed)写入的数据量;kB_read:读取的总数据量;kB_wrtn:写入的总数量数据量;这些单位都为Kilobytes。
上面的例子中,我们可以看到磁盘sda以及它的各个分区的统计数据,当时统计的磁盘总TPS是39.29,下面是各个分区的TPS。(因为是瞬间值,所以总TPS并不严格等于各个分区TPS的总和)
2.-x参数
使用-x参数我们可以获得更多统计信息。
iostat-d-x-k110
Device:rrqm/swrqm/sr/sw/srsec/swsec/srkB/swkB/savgrq-szavgqu-szawaitsvctm%util
sda1.5628.317.8031.4942.512.9221.261.461.160.030.792.6210.28
Device:rrqm/swrqm/sr/sw/srsec/swsec/srkB/swkB/savgrq-szavgqu-szawaitsvctm%util
sda2.0020.00381.007.0012320.00216.006160.00108.0032.311.754.502.1784.20
rrqm/s:每秒这个设备相关的读取请求有多少被Merge了(当系统调用需要读取数据的时候,VFS将请求发到各个FS,如果FS发现不同的读取请求读取的是相同Block的数据,FS会将这个请求合并Merge);wrqm/s:每秒这个设备相关的写入请求有多少被Merge了。
rsec/s:每秒读取的扇区数;wsec/:每秒写入的扇区数。r/s:Thenumberofreadrequeststhatwereissuedtothedevicepersecond;w/s:Thenumberofwriterequeststhatwereissuedtothedevicepersecond;
await:每一个IO请求的处理的平均时间(单位是微秒)。这里可以理解为IO的响应时间,一般地系统IO响应时间应该低于5ms,如果大于10ms就比较大了。
%util:在统计时间内所有处理IO时间,除以总共统计时间。例如,如果统计间隔1秒,该设备有0.8秒在处理IO,而0.2秒闲置,那么该设备的%util=0.8/1=80%,所以该参数暗示了设备的繁忙程度。一般地,如果该参数是100%表示设备已经接近满负荷运行了(当然如果是多磁盘,即使%util是100%,因为磁盘的并发能力,所以磁盘使用未必就到了瓶颈)。
3.-c参数
iostat还可以用来获取cpu部分状态值:
iostat-c110
avg-cpu:%user%nice%sys%iowait%idle
1.980.000.3511.4586.22
avg-cpu:%user%nice%sys%iowait%idle
1.620.000.2534.4663.67
4.常见用法
$iostat-d-k110#查看TPS和吞吐量信息
iostat-d-x-k110#查看设备使用率(%util)、响应时间(await)
iostat-c110#查看cpu状态
5.实例分析
$$iostat-d-k1|grepsda10
Device:tpskB_read/skB_wrtn/skB_readkB_wrtn
sda1060.7218.9571.533956376471493241908
sda10299.024266.67129.414352132
sda10483.844589.904117.1745444076
sda10218.003360.00100.003360100
sda10546.008784.00124.008784124
sda10827.0013232.00136.0013232136
上面看到,磁盘每秒传输次数平均约400;每秒磁盘读取约5MB,写入约1MB。
iostat-d-x-k1
Device:rrqm/swrqm/sr/sw/srsec/swsec/srkB/swkB/savgrq-szavgqu-szawaitsvctm%util
sda1.5628.317.8431.5043.653.1621.821.581.190.030.802.6110.29
sda1.9824.75419.806.9313465.35253.476732.67126.7332.152.004.702.0085.25
sda3.0641.84444.9054.0814204.082048.987102.041024.4932.572.104.211.8592.24
可以看到磁盘的平均响应时间<5ms,磁盘使用率>80。磁盘响应正常,但是已经很繁忙了。
参考文献:
Linuxmaniostat
HowLinuxiostatcomputesitsresults
Linuxiostat
http://blog.csdn.net/AE86_FC/archive/2010/02/03/5284112.aspx
最近要对分布式集群做一些性能测试,其中一个很重要的项就是测试hadoop分布式集群在支持多磁盘轮转写入的时候在各种磁盘配置的情况下的读写性能,如在RAID0,RAID5和JBOD情况下的磁盘性能,所以linux下的iostat命令就在产生report的脚本中非常有用,特此记录下iostat命令的一些使用笔记:
[命令:]iostat[-c|-d][-k][-t][间隔描述][检测次数]
参数:
-c:仅显示cpu的状态
-d:仅显示存储设备的状态,不可以和-c一起使用
-k:默认显示的是读入读出的block信息,用-k可以改成KB大小来显示
-t:显示日期
-pdevice|ALL:device为某个设备或者某个分区,如果使用ALL,就表示要显示所有分区和设备的信息
显示示例:
avg-cpu:%user%nice%sys%iowait%idle
4.550.000.630.2694.56
Device:tpskB_read/skB_wrtn/skB_readkB_wrtn
cciss/c0d030.1168.2067.1312327840601213452142
cciss/c0d0p10.000.000.0025312
cciss/c0d0p283.7868.1867.1112325720111213204536
dm-01.060.604.071087320173555720
dm-182.5067.4262.2312187043091124966656
dm-20.210.180.83319960514929540
dm-30.000.000.00372224
以上显示分为上下两个部分,上半部分显示CPU的信息,下面的数据显示存储设备的相关数据,它的数据意义如下:
tps:平均每秒钟的传送次数,与数据传输“次数”相关,非容量
kB_read/s:启动到现在的平均读取单位
kB_wrtn/s:启动到现在的平均写入单位
kB_read:启动到现在总共读出来的文件单位
kB_wrtn:启动到现在总共写入的文件单位
如果想要对iostat检查多此,每次之间的间隔一定数量的秒数,这样就可以查看每几秒钟之内的io统计数据,这对性能的测试才具有实际意义:
$>iostat-d23
表示没量秒钟检查一次,一共检查三次
avg-cpu:%user%nice%sys%iowait%idle
4.550.000.630.2694.56
Device:tpskB_read/skB_wrtn/skB_readkB_wrtn
cciss/c0d030.1168.2067.1312329002881213456210
cciss/c0d0p10.000.000.0025312
cciss/c0d0p283.7868.1967.1112326882391213208604
dm-01.060.604.071087320173558008
dm-182.5067.4262.2312188205371124967604
dm-20.210.180.83319960514930372
dm-30.000.000.00372224
avg-cpu:%user%nice%sys%iowait%idle
0.000.000.630.0099.37
Device:tpskB_read/skB_wrtn/skB_readkB_wrtn
cciss/c0d01.020.0063.270124
cciss/c0d0p10.000.000.0000
cciss/c0d0p215.820.0063.270124
dm-015.820.0063.270124
dm-10.000.000.0000
dm-20.000.000.0000
dm-30.000.000.0000
avg-cpu:%user%nice%sys%iowait%idle
0.000.000.320.0099.68
Device:tpskB_read/skB_wrtn/skB_readkB_wrtn
cciss/c0d03.060.0026.53052
cciss/c0d0p10.000.000.0000
cciss/c0d0p26.630.0026.53052
dm-00.000.000.0000
dm-16.630.0026.53052
dm-20.000.000.0000
dm-30.000.000.0000
其中每一次的统计都是上一次的统计时间到这次的统计时间之间的统计数据
5.如何查看进程IO读写情况?
2009年08月26日|标签:linux,python|作者:vpsee
LinuxKernel2.6.20以上的内核支持进程IO统计,可以用类似iotop这样的工具来监测每个进程对IO操作的情况,就像用top来实时查看进程内存、CPU等占用情况那样。但是对于2.6.20以下的Linux内核版本就没那么幸运了,根据StackOverflow的这篇回帖给出的方法,VPSee写了一个简单的Python脚本用来在linuxkernel<2.6.20下打印进程IO状况。
Kernel<2.6.20
这个脚本的想法很简单,把dmesg的结果重定向到一个文件后再解析出来,每隔1秒钟打印一次进程IO读写的统计信息,执行这个脚本需要root:
#!/usr/bin/python
#Monitoringper-processdiskI/Oactivity
#writtenbyhttp://www.vpsee.com
importsys,os,time,signal,re
classDiskIO:
def__init__(self,pname=None,pid=None,reads=0,writes=0):
self.pname=pname
self.pid=pid
self.reads=0
self.writes=0
defmain():
argc=len(sys.argv)
ifargc!=1:
print"usage:./iotop"
sys.exit(0)
ifos.getuid()!=0:
print"mustberunasroot"
sys.exit(0)
signal.signal(signal.SIGINT,signal_handler)
os.system('echo1>/proc/sys/vm/block_dump')
print"TASKPIDREADWRITE"
whileTrue:
os.system('dmesg-c>/tmp/diskio.log')
l=[]
f=open('/tmp/diskio.log','r')
line=f.readline()
whileline:
m=re.match(\
'^(\S+)\((\d+)\):(READ|WRITE)block(\d+)on(\S+)',line)
ifm!=None:
ifnotl:
l.append(DiskIO(m.group(1),m.group(2)))
line=f.readline()
continue
found=False
foriteminl:
ifitem.pid==m.group(2):
found=True
ifm.group(3)=="READ":
item.reads=item.reads+1
elifm.group(3)=="WRITE":
item.writes=item.writes+1
ifnotfound:
l.append(DiskIO(m.group(1),m.group(2)))
line=f.readline()
time.sleep(1)
foriteminl:
print"%-10s%10s%10d%10d"%\
(item.pname,item.pid,item.reads,item.writes)
defsignal_handler(signal,frame):
os.system('echo0>/proc/sys/vm/block_dump')
sys.exit(0)
if__name__=="__main__":
main()
Kernel>=2.6.20
如果想用iotop来实时查看进程IO活动状况的话,需要下载和升级新内核(2.6.20或以上版本)。编译新内核时需要打开TASK_DELAY_ACCT和TASK_IO_ACCOUNTING选项。解压内核后进入配置界面:
#tarjxvflinux-2.6.30.5.tar.bz2
#mvlinux-2.6.30.5/usr/src/
#cd/usr/src/linux-2.6.30.5
#makemenuconfig
选择Kernelhacking–>Collectschedulerdebugginginfo和Collectschedulerstatistics,保存内核后编译内核:
#make;makemodules;makemodules_install;makeinstall
修改grub,确认能正确启动新内核:
#vi/boot/grub/menu.lst
出了新内核外,iotop还需要Python2.5或以上才能运行,所以如果当前Python是2.4的话需要下载和安装最新的Python包。这里使用源代码编译安装:
#tarjxvfPython-2.6.2.tar.bz2
#cdPython-2.6.2
#./configure
#make;makeinstall
别忘了下载setuptools:
#mvsetuptools-0.6c9-py2.6.egg.shsetuptools-0.6c9-py2.6.egg
#shsetuptools-0.6c9-py2.6.egg
更多信息
如果想知道更多关于block_dump的信息,可以看看这篇监测Linux进程的实时IO情况。使用block_dump的时候,最好能关掉klogd进程