1. /proc/partitions
iostat 的数据的主要来源是 /proc/partitions,所以需要先看看
/proc/partitions 中有些什么。
# cat /proc/partitions
major minor #blocks name rio rmerge rsect ruse wio wmerge wsect wuse running use aveq
3 0 19535040 hda 12524 31127 344371 344360 12941 25534 308434 1097290 -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 0 46520 146650
3 7 6980211 hda7 11889 30475 338890 340740 12683 22158 279376 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
Linux2.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/s avgrq-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.50 11.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.00 10.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.00 6.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.15 193.96 52.25 0.41
/dev/hda7 1.66 1.33 0.76 0.79 19.41 16.97 9.70 8.49 23.44 0.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.00 4.31 79.44
Device: rrqm/s wrqm/s r/s w/s rsec/s wsec/s rkB/s wkB/s avgrq-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.35 78.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.35 78.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.00 0.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是Virtual Meomory Statistics(虚拟内存统计)的缩写,可对操作系统的虚拟内存、进程、CPU活动进行监视。它是对系统的整体情况进行统计,不足之处是无法对某个进程进行深入分析。
vmstat的语法如下:
程序代码
vmstat [-V] [-n] [delay [count]]
procs memory page disk faults cpu r b w swap free re mf mi po 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 0 0 8 198 2158 98 11 19 69 SWAP的单位应该是K,不是M。还有两个比较重要的参数是PI、PO,表示内存的调入、调出页面,单位也是K,但是多大值作为一个衡量标准,我也不清楚,不知道是否有经验值。 还有,最好使用vmstat t [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/2001 14:43:50 %usr %sys %wio %idle(-u) 14:44:50 0 1 4 94 14:45:50 0 2 4 93 14:46:50 0 2 2 96 14:47:50 0 2 5 93 14:48:50 0 2 2 96 Average 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 ov file-sz ov lock-sz (-v) 10:33:53 305/ 321 0 1337/2764 0 1561/1706 0 40/ 128 10:34:23 308/ 321 0 1340/2764 0 1587/1706 0 37/ 128 10:34:53 305/ 321 0 1332/2764 0 1565/1706 0 36/ 128 10:35:23 308/ 321 0 1338/2764 0 1592/1706 0 37/ 128 10: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_SV scosysv 3.2v5.0.5 i80386 10/01/2001 11:06:43 device %busy avque r+w/s blks/s avwait avserv (-d) 11:07:13 wd-0 1.47 2.75 4.67 14.73 5.50 3.14 11:07:43 wd-0 0.43 18.77 3.07 8.66 25.11 1.41 11:08:13 wd-0 0.77 2.78 2.77 7.26 4.94 2.77 11:08:43 wd-0 1.10 11.18 4.10 11.26 27.32 2.68 11:09:13 wd-0 1.97 21.78 5.86 34.06 69.66 3.35 Average wd-0 1.15 12.11 4.09 15.19 31.12 2.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_SV scosysv 3.2v5.0.5 i80386 10/01/2001 14:54:59 bread/s lread/s %rcachebwrit/s lwrit/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: 在buffer cache中进行逻辑读的百分比。 bwrit/s: 平均每秒从系统buffer向磁盘所写的物理块数。 lwrit/s: 平均每秒写到系统buffer逻辑块数。 %wcache: 在buffer cache中进行逻辑读的百分比。 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.00 17:08:03 0.00 0.00 0.00 17:08:33 0.00 0.00 0.00 17:09:03 0.00 0.00 0.00 17:09:33 0.00 0.00 0.00 Average 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来看,以上举出的五例仅仅是其中的一部分,有兴趣的朋友不妨一试。