Linux 性能分析工具(vmstat,iostat,sar)
. /proc/partitions iostat 的数据的主要来源是 /proc/partitions,所以需要先看看/proc/partitions 中有些什么。# cat /proc/partitions major minor #blocks name rio rmerge rsect ruse wiowmerge wsect wuse running use aveq 3 0 19535040 hda 1252
1. /proc/partitions
iostat 的数据的主要来源是/proc/partitions,所以需要先看看
/proc/partitions 中有些什么。
# cat /proc/partitions
major minor #blocks name rio rmerge rsect ruse wio wmergewsect wuse running use aveq
3 0 19535040 hda 12524 31127 344371 344360 12941 25534 3084341097290 -1 15800720 28214662
3 1 7172991 hda1 13 71 168 140 0 0 0 0 0 140 140
3 2 1 hda2 0 0 0 0 0 0 0 0 0 0 0
3 5 5116671 hda5 100 477 665 620 1 1 2 30 0 610 650
3 6 265041 hda6 518 92 4616 2770 257 3375 29056 143880 046520 146650
3 7 6980211 hda7 11889 30475 338890 340740 12683 22158279376 953380 0 509350 1294120
major: 主设备号。3 代表 hda。
minor: 次设备号。7 代表 No.7 分区。
#blocks: 设备总块数(1024 bytes/block)。19535040*1024=> 20003880960(bytes) ~2G
name: 设备名称。如hda7。
rio: 完成的读I/O 设备总次数。指真正向I/O 设备发起并完成的读操作数目,
也就是那些放到 I/O 队列中的读请求。注意很多进程发起的读操作
(read())很可能会和其他的操作进行merge,不一定每个read() 调用
都引起一个 I/O 请求。
rmerge: 进行了merge 的读操作数目。
rsect: 读扇区总数(512 bytes/sector)
ruse: 从进入读队列到读操作完成的时间累积(毫秒)。上面的例子显示从开机
开始,读hda7 操作共用了约340秒。
wio: 完成的写 I/O设备总次数。
wmerge: 进行了merge 的写操作数目。
wsect: 写扇区总数
wuse: 从进入写队列到写操作完成的时间累积(毫秒)
running: 已进入I/O 请求队列,等待进行设备操作的请求总数。上面的例子显
示 hda7 上的请求队列长度为 0。
use: 扣除重叠等待时间的净等待时间(毫秒)。一般比(ruse+wuse) 要小。比
如 5 个读请求同时等待了 1 毫秒,那么 ruse值为5ms, 而 use值为
1ms。use 也可以理解为I/O队列处于不为空状态的总时间。hda7的I/O
队列非空时间为 509 秒,约合8分半钟。
aveq: 在队列中总的等待时间累积(毫秒)(约等于ruse+wuse)
2. iostat 结果解析
# iostat -x
Linux 2.4.21-9.30AX (localhost) 2004年07月14日
avg-cpu: %user %nice %sys %idle
3.85 0.00 0.95 95.20
Device: rrqm/s wrqm/s r/s w/s rsec/s wsec/s rkB/s wkB/savgrq-sz avgqu-sz await svctm %util
/dev/hda 1.70 1.70 0.82 0.82 19.88 20.22 9.94 10.11 24.5011.83 57.81 610.76 99.96
/dev/hda1 0.00 0.00 0.00 0.00 0.01 0.00 0.00 0.00 12.92 0.0010.77 10.77 0.00
/dev/hda5 0.02 0.00 0.00 0.00 0.03 0.00 0.02 0.00 6.60 0.006.44 6.04 0.00
/dev/hda6 0.01 0.38 0.05 0.03 0.43 3.25 0.21 1.62 46.90 0.15193.96 52.25 0.41
/dev/hda7 1.66 1.33 0.76 0.79 19.41 16.97 9.70 8.49 23.440.79 51.13 19.79 3.07
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系统已经满负荷,该磁盘
可能存在瓶颈。
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 洪水。
3. 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 的速度和响应时间。
4. 一个例子
# iostat -x 1
avg-cpu: %user %nice %sys %idle
16.24 0.
Device: rrqm/s wrqm/s r/s w/s rsec/s wsec/s rkB/s wkB/savgrq-sz avgqu-sz await svctm %util
/dev/cciss/c0d0
0.00 44.90 1.02 27.55 8.16 579.59 4.08 289.80 20.57 22.3578.21 5.00 14.29
/dev/cciss/c0d0p1
0.00 44.90 1.02 27.55 8.16 579.59 4.08 289.80 20.57 22.3578.21 5.00 14.29
/dev/cciss/c0d0p2
0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.000.00
上面的iostat 输出表明秒有28.57 次设备I/O 操作:delta(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。
用vmstat监视内存使用情况
vmstat是VirtualMeomory Statistics(虚拟内存统计)的缩写,可对操作系统的虚拟内存、进程、CPU活动进行监视。它是对系统的整体情况进行统计,不足之处是无法对某个进程进行深入分析。
vmstat的语法如下:
程序代码
vmstat [-V] [-n] [delay [count]]
procs memory page disk faults cpu r b w swap free re mf mipo fr de sr f0 s0 s1 s2 in sy cs us sy id 0 0 0 14888 19120 0 4 2 11 10 0 0 0 00 8 198 2158 98 11 19 69 SWAP的单位应该是K,不是M。还有两个比较重要的参数是PI、PO,表示内存的调入、调出页面,单位也是K,但是多大值作为一个衡量标准,我也不清楚,不知道是否有经验值。还有,最好使用vmstatt [n]命令,例如vmstat 5 5,表示在T(5)秒时间内进行N(5)次采样。如果只使用vmstat,无法反映真正的系统情况,试一下,看看结果就知道了。procs: r–>在运行队列中等待的进程数b–>在等待io的进程数 w–>可以进入运行队列但被替换的进程memoy swap–>现时可用的交换内存(k表示) free–>空闲的内存(k表示)pages re--》回收的页面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性能不好。
在使用UNIX操作系统的过程中,我们常常会用到各种各样的问题,比如系统运行速度突然变慢,系统容易死机或者主机所带的终端常出现死机,这时我们常常猜测,是硬盘空间太小,还是内存不足?I/O出现瓶颈,或者是系统的核心参数出了问题?这时,我们应该考虑使用系统给我们提供的sar命令来对系统作一个了解,该命令是系统维护的重要工具,主要帮助我们掌握系统资源的使用情况,特别是内存和CPU的使用情况,是UNIX系统使用者应该掌握的工具之一。sar 命令行的常用格式:
sar [options] [-A] [-o file] t [n]
在命令行中,n和t两个参数组合起来定义采样间隔和次数,t为采样间隔,是必须有的参数,n为采样次数,是可选的,默认值是1,-o file表示将命令结果以二进制格式存放在文件中,file在此处不是关键字,是文件名。options为命令行选项,sar命令的选项很多,下面只列出常用选项:
-A:所有报告的总和。-u:CPU利用率 -v:进程、I节点、文件和锁表状态。-d:硬盘使用报告。-r:没有使用的内存页面和硬盘块。-g:串口I/O的情况。 -b:缓冲区使用情况。-a:文件读写情况。-c:系统调用情况。-R:进程的活动情况。-y:终端设备活动情况。-w:系统交换活动。
下面将举例说明。
例一:使用命令行sar -u t n
例如,每60秒采样一次,连续采样5次,观察CPU 的使用情况,并将采样结果以二进制形式存入当前目录下的文件zhou中,需键入如下命令:
# sar -u -o zhou 60 5
屏幕显示:
SCO_SV scosysv 3.2v5.0.5 i80386 10/01/200114:43:50 %usr %sys %wio %idle(-u)14:44:50 0 1 4 9414:45:50 0 2 4 9314:46:50 0 2 2 9614:47:50 0 2 5 9314:48:50 0 2 2 96Average 0 2 4 94
在显示内容包括:
%usr:CPU处在用户模式下的时间百分比。%sys:CPU处在系统模式下的时间百分比。%wio:CPU等待输入输出完成时间的百分比。%idle:CPU空闲时间百分比。
在所有的显示中,我们应主要注意%wio和%idle,%wio的值过高,表示硬盘存在I/O瓶颈,%idle值高,表示CPU较空闲,如果%idle值高但系统响应慢时,有可能是CPU等待分配内存,此时应加大内存容量。%idle值如果持续低于10,那么系统的CPU处理能力相对较低,表明系统中最需要解决的资源是CPU。
如果要查看二进制文件zhou中的内容,则需键入如下sar命令:
#sar -u -f zhou
可见,sar命令即可以实时采样,又可以对以往的采样结果进行查询。
例二:使用命行sar-v t n
例如,每30秒采样一次,连续采样5次,观察核心表的状态,需键入如下命令:
# sar -v 30 5
屏幕显示:SCO_SV scosysv 3.2v5.0.5 i80386 10/01/2001 10:33:23 proc-sz ov inod-sz ovfile-sz ov lock-sz (-v) 10:33:53 305/ 321 0 1337/2764 0 1561/1706 0 40/ 12810:34:23 308/ 321 0 1340/2764 0 1587/1706 0 37/ 12810:34:53 305/ 321 0 1332/2764 0 1565/1706 0 36/ 12810:35:23 308/ 321 0 1338/2764 0 1592/1706 0 37/ 12810:35:53 308/ 321 0 1335/2764 0 1591/1706 0 37/ 128
显示内容包括:
proc-sz:目前核心中正在使用或分配的进程表的表项数,由核心参数MAX-PROC控制。
inod-sz:目前核心中正在使用或分配的i节点表的表项数,由核心参数MAX-INODE控制。
file-sz:目前核心中正在使用或分配的文件表的表项数,由核心参数MAX-FILE控制。
ov:溢出出现的次数。
Lock-sz:目前核心中正在使用或分配的记录加锁的表项数,由核心参数MAX-FLCKRE控制。
显示格式为
实际使用表项/可以使用的表项数
显示内容表示,核心使用完全正常,三个表没有出现溢出现象,核心参数不需调整,如果出现溢出时,要调整相应的核心参数,将对应的表项数加大。
例三:使用命行sar-d t n
例如,每30秒采样一次,连续采样5次,报告设备使用情况,需键入如下命令:
# sar -d 30 5
屏幕显示:
SCO_SVscosysv 3.2v5.0.5 i80386 10/01/2001 11:06:43 device %busy avque r+w/s blks/s avwait avserv (-d) 11:07:13wd-0 1.47 2.75 4.67 14.73 5.503.14 11:07:43 wd-0 0.43 18.77 3.07 8.66 25.111.41 11:08:13 wd-0 0.77 2.78 2.77 7.26 4.942.77 11:08:43 wd-0 1.10 11.18 4.10 11.26 27.322.68 11:09:13 wd-0 1.97 21.78 5.86 34.06 69.663.35 Average wd-0 1.15 12.11 4.09 15.19 31.122.80
显示内容包括:
device:sar命令正在监视的块设备的名字。%busy:设备忙时,传送请求所占时间的百分比。avque:队列站满时,未完成请求数量的平均值。r+w/s:每秒传送到设备或从设备传出的数据量。blks/s:每秒传送的块数,每块512字节。avwait:队列占满时传送请求等待队列空闲的平均时间。avserv:完成传送请求所需平均时间(毫秒)。
在显示的内容中,wd-0是硬盘的名字,%busy的值比较小,说明用于处理传送请求的有效时间太少,文件系统效率不高,一般来讲,%busy值高些,avque值低些,文件系统的效率比较高,如果%busy和avque值相对比较高,说明硬盘传输速度太慢,需调整。
例四:使用命行sar-b t n
例如,每30秒采样一次,连续采样5次,报告缓冲区的使用情况,需键入如下命令:
# sar -b 30 5
屏幕显示:
SCO_SVscosysv 3.2v5.0.5 i80386 10/01/2001 14:54:59 bread/s lread/s %rcache bwrit/slwrit/s %wcache pread/s pwrit/s (-b) 14:55:29 0 147 100 5 21 78 0 0 14:55:59 0 186 100 5 25 79 0 0 14:56:29 4 232 98 8 58 86 0 0 14:56:59 0 125 100 5 23 76 0 0 14:57:29 0 89 100 4 12 66 0 0 Average 1 156 99 5 28 80 0 0
显示内容包括:
bread/s:每秒从硬盘读入系统缓冲区buffer的物理块数。lread/s:平均每秒从系统buffer读出的逻辑块数。%rcache:在buffercache中进行逻辑读的百分比。bwrit/s:平均每秒从系统buffer向磁盘所写的物理块数。lwrit/s:平均每秒写到系统buffer逻辑块数。%wcache:在buffercache中进行逻辑读的百分比。pread/s:平均每秒请求物理读的次数。pwrit/s:平均每秒请求物理写的次数。
在显示的内容中,最重要的是%cache和%wcache两列,它们的值体现着buffer的使用效率,%rcache的值小于90或者%wcache的值低于65,应适当增加系统buffer的数量,buffer数量由核心参数NBUF控制,使%rcache达到90左右,%wcache达到80左右。但buffer参数值的多少影响I/O效率,增加buffer,应在较大内存的情况下,否则系统效率反而得不到提高。
例五:使用命行sar-g t n
例如,每30秒采样一次,连续采样5次,报告串口I/O的操作情况,需键入如下命令:
# sar -g 30 5
屏幕显示:
SCO_SV scosysv 3.2v5.0.5 i80386 11/22/2001 17:07:03 ovsiohw/s ovsiodma/s ovclist/s(-g) 17:07:33 0.00 0.00 0.0017:08:03 0.00 0.00 0.0017:08:33 0.00 0.00 0.0017:09:03 0.00 0.00 0.0017:09:33 0.00 0.00 0.00Average 0.00 0.00 0.00
显示内容包括:
ovsiohw/s:每秒在串口I/O硬件出现的溢出。
ovsiodma/s:每秒在串口I/O的直接输入输出通道高速缓存出现的溢出。
ovclist/s :每秒字符队列出现的溢出。
在显示的内容中,每一列的值都是零,表明在采样时间内,系统中没有发生串口I/O溢出现象。
sar命令的用法很多,有时判断一个问题,需要几个sar命令结合起来使用,比如,怀疑
CPU存在瓶颈,可用sar-u 和sar-q来看,怀疑I/O存在瓶颈,可用sar-b、sar-u和
sar-d来看,以上举出的五例仅仅是其中的一部分,有兴趣的朋友不妨一试。