xingzhegu 2011-09-09
Linux在具有高稳定性、可靠性的同时,具有很好的可伸缩性和扩展性,能够针对不同的应用和硬件环境调整,优化出满足当前应用需要的最佳性能。因此企业在维护Linux系统、进行系统调优时,了解系统性能分析工具是至关重要的。
在Linux下有很多系统性能分析工具,比较常见的有top、free、ps、time、timex、uptime等。下文将介绍几个较为重要的性能分析工具vmstat、iostat和sar及其使用。
1.用vmstat监视内存使用情况
vmstat是VirtualMeomoryStatistics(虚拟内存统计)的缩写,可对操作系统的虚拟内存、进程、CPU活动进行监视。它是对系统的整体情况进行统计,不足之处是无法对某个进程进行深入分析。
vmstat的语法如下:
程序代码
vmstat[-V][-n][delay[count]]
其中,-V表示打印出版本信息;-n表示在周期性循环输出时,输出的头部信息仅显示一次;delay是两次输出之间的延迟时间;count是指按照这个时间间隔统计的次数。对于vmstat输出各字段的含义,可运行manvmstat查看。
ProCS
r:等待运行的进程数b:处在非中断睡眠状态的进程数w:被交换出去的可运行的进程数。此数由Linux计算得出,但linux并不耗尽交换空间
Memory
swpd:虚拟内存使用情况,单位:KB
free:空闲的内存,单位KB
buff:被用来做为缓存的内存数,单位:KB
Swap
si:从磁盘交换到内存的交换页数量,单位:KB/秒
so:从内存交换到磁盘的交换页数量,单位:KB/秒
IO
bi:发送到块设备的块数,单位:块/秒
bo:从块设备接收到的块数,单位:块/秒
System
in:每秒的中断数,包括时钟中断
cs:每秒的环境(上下文)切换次数
CPU
按CPU的总使用百分比来显示
us:CPU使用时间
sy:CPU系统使用时间
id:闲置时间
准测
r<5,b≈0,
如果fre对于page列,re,pi,po,cy维持于比较稳定的状态,PI率不超过5,如果有pagin发生,那么关联页面必须先进行pageout在内存相对紧张的环境下pagein会强制对不同的页面进行steal操作。如果系统正在读一个大批的永久页面,你也许可以看到po和pi列会出现不一致的增长,这种情景并不一定表明系统负载过重,但是有必要对应用程序的数据访问模式进行见检查。在稳定的情况下,扫描率和重置率几乎相等,在多个进程处理使用不同的页面的情况下,页面会更加不稳定和杂乱,这时扫描率可能会比重置率高出。
faults列,in,sy,cs会不断跳跃,这里没有明确的限制,唯一的就是这些值最少大于100cpu列,us,sys,id和wa也是不确定的,最理想的状态是使cpu处于100%工作状态,单这只适合单用户的情况下。
如果在多用户环境中us+sys》80,进程就会在运行队列中花费等待时间,响应时间和吞吐量就会下降。wa>40表明磁盘io没有也许存在不合理的平衡,或者对磁盘操作比较频繁,vmstat各项:
procs:r-->在运行队列中等待的进程数b-->在等待io的进程数w-->可以进入运行队列但被替换的进程memoyswap-->现时可用的交换内存(k表示)free-->空闲的内存(k表示)pagesre--》回收的页面mf--》非严重错误的页面pi--》进入页面数(k表示)po--》出页面数(k表示)fr--》空余的页面数(k表示)de--》提前读入的页面中的未命中数sr--》通过时钟算法扫描的页面disk显示每秒的磁盘操作。s表示scsi盘,0表示盘号fault显示每秒的中断数in--》设备中断sy--》系统中断cy--》cpu交换cpu表示cpu的使用状态cs--》用户进程使用的时间sy--》系统进程使用的时间id--》cpu空闲的时间
如果r经常大于4,且id经常少于40,表示cpu的负荷很重。
如果pi,po长期不等于0,表示内存不足。
如果disk经常不等于0,且在b中的队列大于3,表示io性能不好。
2.用iostat监视I/O子系统情况
iostat是I/Ostatistics(输入/输出统计)的缩写,iostat工具将对系统的磁盘操作活动进行监视。它的特点是汇报磁盘活动统计情况,同时也会汇报出CPU使用情况。同vmstat一样,iostat也有一个弱点,就是它不能对某个进程进行深入分析,仅对系统的整体情况进行分析。
iostat的语法如下:
程序代码
iostat[-c|-d][-k][-t][-V][-x[device]][interval[count]]
其中,-c为汇报CPU的使用情况;-d为汇报磁盘的使用情况;-k表示每秒按kilobytes字节显示数据;-t为打印汇报的时间;-v表示打印出版本信息和用法;-xdevice指定要统计的设备名称,默认为所有的设备;interval指每次统计间隔的时间;count指按照这个时间间隔统计的次数。
iostat一般的输出格式如下:
程序代码
Linux2.4.18-18smp(builder.linux.com)2003年03月07日
avg-cpu:%user%nice%sys%idle
4.810.011.0394.15
Device:tpsBlk_read/sBlk_wrtn/sBlk_readBlk_wrtn
dev3-030.311117.68846.521610453612197374
dev3-17.06229.6140.403308486582080
-------------------------------------------------------------------------------
iostat在内核2.4和内核2.6中数据来源不太一样,所以我们分别就这两中系统介绍iostat的输出。
1.内核2.4iostat输出解析
对于kernel2.4,iostat的数据的主要来源是/proc/partitions。
1.1/proc/partition
先看看/proc/partitions中有些什么。
#cat/proc/partitions
majorminor#blocksnameriormergersectruse
3019535040hda1252431127344371344360
wiowmergewsectwuserunninguseaveq
12941255343084341097290-11580072028214662
下面是每项数据的说明:
major:主设备号。
minor:次设备号。
#blocks:设备总块数(1024bytes/block)。
name:设备名称。如hda7。
rio:完成的读I/O设备总次数。指真正向I/O设备发起并完成的读操作数目,
也就是那些放到I/O队列中的读请求。注意很多进程发起的读操作
(read())很可能会和其他的操作进行merge,不一定每个read()调用
都引起一个I/O请求。
rmerge:进行了merge的读操作数目。
rsect:读扇区总数(512bytes/sector)
ruse:从进入读队列到读操作完成的时间累积(毫秒)。上面的例子显示从开机
开始,读hda7操作共用了约340秒。
wio:完成的写I/O设备总次数。
wmerge:进行了merge的写操作数目。
wsect:写扇区总数
wuse:从进入写队列到写操作完成的时间累积(毫秒)
running:已进入I/O请求队列,等待进行设备操作的请求总数。上面的例子显
示磁盘上请求队列长度为0。
use:扣除重叠等待时间的净等待时间(毫秒)。一般比(ruse+wuse)要小。比
如5个读请求同时等待了1毫秒,那么ruse值为5ms,而use值为
1ms。use也可以理解为I/O队列处于不为空状态的总时间。hda7的I/O
队列非空时间为509秒,约合8分半钟。
aveq:在队列中总的等待时间累积(毫秒)(约等于ruse+wuse)
1.2iostat结果解析
#iostat-x
Linux2.4.21-9.30AX(localhost)
avg-cpu:%user%nice%sys%idle
3.850.000.9595.20
Device:rrqm/swrqm/sr/sw/srsec/swsec/s
/dev/hda1.701.700.820.8219.8820.22
rkB/swkB/savgrq-szavgqu-szawaitsvctm%util
9.9410.1124.5011.8357.81610.7699.96
每项数据的含义如下,
rrqm/s:每秒进行merge的读操作数目。即rmerge/s
wrqm/s:每秒进行merge的写操作数目。即wmerge/s
r/s:每秒完成的读I/O设备次数。即rio/s
w/s:每秒完成的写I/O设备次数。即wio/s
rsec/s:每秒读扇区数。即rsect/s
wsec/s:每秒写扇区数。即wsect/s
rkB/s:每秒读K字节数。是rsect/s的一半,因为每扇区大小为512字节。
wkB/s:每秒写K字节数。是wsect/s的一半。
avgrq-sz:平均每次设备I/O操作的数据大小(扇区)。即(rsect+wsect)/(rio+wio)
avgqu-sz:平均I/O队列长度。即aveq/1000(因为aveq的单位为毫秒)。
await:平均每次设备I/O操作的等待时间(毫秒)。即(ruse+wuse)/(rio+wio)
svctm:平均每次设备I/O操作的服务时间(毫秒)。即use/(rio+wio)
%util:一秒中有百分之多少的时间用于I/O操作,或者说一秒中有多少时间
I/O队列是非空的,即use/1000(因为use的单位为毫秒),
如果%util接近100%,说明产生的I/O请求太多,I/O系统已经满负荷,该磁盘可能存在瓶颈。
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洪水。
1.3一个例子
#iostat-x1
avg-cpu:%user%nice%sys%idle
16.240.004.3179.44
Device:rrqm/swrqm/sr/sw/srsec/swsec/s
/dev/cciss0.0044.901.0227.558.16579.59
rkB/swkB/savgrq-szavgqu-szawaitsvctm%util
4.08289.8020.5722.3578.215.0014.29
上面的iostat输出表明秒有28.57次设备I/O操作: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毫秒之内处理掉了。
(ruse+wuse)/io=await=78.21=>(ruse+wuse)/s=78.21*(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。
iostat.c中是这样计算avgqu-sz的:
((double)current.aveq)/itv
aveq的单位是毫秒,而itv是两次采样之间的间隔,单位是jiffies。必须换
算成同样单位才能相除,所以正确的算法是:
(((double)current.aveq)/1000)/(itv/HZ)
这样,上面iostat中输出的avgqu-sz值应为2.23,而不是22.3。
2.内核2.6iostat输出解析
在2.6中,数据来源主要是/proc/diskstats和/sys/block/sd*/stat这两个文件,下面分别介绍这两个文件中各项数据的含义。
2.1/proc/diskstats
cat/proc/diskstats|grepsda
80sda470792145771623274423897542113502076
276664326820024160144224415
81sda17386252826744465336
82sda2609103620743844220197216
其信息与2.4中/proc/partition类似,但没有标题栏,上面的信息中首先是磁盘的信息,后面接着的是磁盘分区的信息。
我们首先看磁盘的信息,总共有14列信息(标记为红色的部分)。
Field1:磁盘主设备号(major)
Field2:磁盘次设备号(minor)
Field3:磁盘的设备名(name)
Field4:读请求总数(rio)
Field5:合并的读请求总数(rmerge)
Field6:读扇区总数(rsect)
Field7:读数据花费的时间,单位是ms.(从__make_request到end_that_request_last)(ruse)
Field8:写请求总数(wio)
Field9:合并的写请求总数(wmerge)
Field10:写扇区总数(wsect)
Field11:写数据花费的时间,单位是ms.(从__make_request到end_that_request_last)(wuse)
Field12:现在正在进行的I/O数(running),等于I/O队列中请求数
Field13:系统真正花费在I/O上的时间,除去重复等待时间(aveq)
Field14:系统在I/O上花费的时间(use)。
我们再看分区信息(标记为紫色的部分)
这部分信息比较简单,除了前面的主次设备号和设备名外,后面依次分别是:读请求数,读扇区数,写请求数,写扇区数。
2.2/sys/block/sd*/stat
Cat/sys/block/sda/stat
470792145771623274423897542113592078276752327045024160534224640
这些数据其实与/proc/diskstats中除设备号与设备名外的其它数据是一一对应关系,只是统计的方法略有差别而已。
------------------------------------------------------------------------------
对于输出中各字段的含义,iostat的帮助中有详细的说明。
使用sar进行综合分析
表1sar参数说明
选项功能
-A汇总所有的报告
-a报告文件读写使用情况
-B报告附加的缓存的使用情况
-b报告缓存的使用情况
-c报告系统调用的使用情况
-d报告磁盘的使用情况
-g报告串口的使用情况
-h报告关于buffer使用的统计数据
-m报告IPC消息队列和信号量的使用情况
-n报告命名cache的使用情况
-p报告调页活动的使用情况
-q报告运行队列和交换队列的平均长度
-R报告进程的活动情况
-r报告没有使用的内存页面和硬盘块
-u报告CPU的利用率
-v报告进程、i节点、文件和锁表状态
-w报告系统交换活动状况
-y报告TTY设备活动状况
sar是SystemActivityReporter(系统活动情况报告)的缩写。顾名思义,sar工具将对系统当前的状态进行取样,然后通过计算数据和比例来表达系统的当前运行状态。它的特点是可以连续对系统取样,获得大量的取样数据;取样数据和分析的结果都可以存入文件,所需的负载很小。sar是目前Linux上最为全面的系统性能分析工具之一,可以从14个大方面对系统的活动进行报告,包括文件的读写情况、系统调用的使用情况、串口、CPU效率、内存使用状况、进程活动及IPC有关的活动等,使用也是较为复杂。
sar的语法如下:
程序代码
sar[-option][-ofile]t[n]
它的含义是每隔t秒取样一次,共取样n次。其中-ofile表示取样结果将以二进制形式存入文件file中。
另一种语法如下:程序代码
sar[-option][-stime][-etime][-isec][-ffile]
含义是表示从file文件中取出数据,如果没有指定-ffile,则从标准数据文件/var/adm/sa/sadd取数据,其中dd表示当前天。另外,-stime表示起始时间;-etime表示停止时间;-isec表示取样的时间间隔,如果不指定则表示取文件中所有的数据。对于具体的选项参见表1。
一般它与-q和-u联合使用,以便对每个CPU的使用情况进行分析,比如运行如下命令:
程序代码
sar-q-u51
将输出如下:
程序代码
Linux2.4.18-18smp(builder.linux.com)2003年03月07日
09时46分16?CPU%user%nice%system%idle
09时46分21?all0.200.000.0099.80
09时46分16?runq-szplist-szldavg-1ldavg-5
09时46分21?0910.000.00
Average:CPU%user%nice%system%idle
Average:all0.200.000.0099.80
Average:runq-szplist-szldavg-1ldavg-5
Average:0910.000.00