Linux系统中的 iostat是I/O statistics(输入/输出统计)的缩写,iostat工具将对系统的磁盘操作活动进行监视。它的特点是汇报磁盘活动统计情况,同时也会汇报出CPU使用情况。同vmstat一样,iostat也有一个弱点,就是它不能对某个进程进行深入分析,仅对系统的整体情况进行分析。iostat属于sysstat软件包。可以用yum install sysstat 直接安装。
1.命令格式:
iostat[参数][时间][次数]
2.命令功能:
通过iostat方便查看CPU、网卡、tty设备、磁盘、CD-ROM 等等设备的活动情况, 负载信息。
3.命令参数:
-C 显示CPU使用情况
-d 显示磁盘使用情况
-k 以 KB 为单位显示
-m 以 M 为单位显示
-N 显示磁盘阵列(LVM) 信息
-n 显示NFS 使用情况
-p[磁盘] 显示磁盘和分区的情况
-t 显示终端和CPU的信息
-x 显示详细信息
-V 显示版本信息
4. 常见用法
iostat -d -k 1 10 #查看TPS和吞吐量信息
iostat -d -x -k 1 10 #查看设备使用率(%util)、响应时间(await)
iostat -c 1 10 #查看cpu状态
实例1:显示所有设备负载情况
命令:
iostat
输出:
[root@CT1186 ~]# iostatLinux 2.6.18-128.el5 (CT1186) 2012年12月28日
avg-cpu: %user %nice %system %iowait %steal %idle
8.30 0.02 5.07 0.17 0.00 86.44
Device: tps Blk_read/s Blk_wrtn/s Blk_read Blk_wrtn
sda 22.73 43.70 487.42 674035705 7517941952
sda1 0.00 0.00 0.00 2658 536
sda2 0.11 3.74 3.51 57721595 54202216
sda3 0.98 0.61 17.51 9454172 270023368
sda4 0.00 0.00 0.00 6 0
sda5 6.95 0.12 108.73 1924834 1677123536
sda6 2.20 0.18 31.22 2837260 481488056
sda7 12.48 39.04 326.45 602094508 5035104240
说明:
cpu属性值说明:
%user:CPU处在用户模式下的时间百分比。
%nice:CPU处在带NICE值的用户模式下的时间百分比。
%system:CPU处在系统模式下的时间百分比。
%iowait:CPU等待输入输出完成时间的百分比。
%steal:管理程序维护另一个虚拟处理器时,虚拟CPU的无意识等待时间百分比。
%idle:CPU空闲时间百分比。
备注:如果%iowait的值过高,表示硬盘存在I/O瓶颈,%idle值高,表示CPU较空闲,如果%idle值高但系统响应慢时,有可能是CPU等待分配内存,此时应加大内存容量。%idle值如果持续低于10,那么系统的CPU处理能力相对较低,表明系统中最需要解决的资源是CPU。
disk属性值说明:
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操作的数据大小 (扇区)。
avgqu-sz: 平均I/O队列长度。
await: 平均每次设备I/O操作的等待时间 (毫秒)。
svctm: 平均每次设备I/O操作的服务时间 (毫秒)。
%util: 一秒中有百分之多少的时间用于 I/O 操作,即被io消耗的cpu百分比
备注:如果 %util 接近 100%,说明产生的I/O请求太多,I/O系统已经满负荷,该磁盘可能存在瓶颈。如果 svctm 比较接近 await,说明 I/O 几乎没有等待时间;如果 await 远大于 svctm,说明I/O 队列太长,io响应太慢,则需要进行必要优化。如果avgqu-sz比较大,也表示有当量io在等待。
实例2:查看TPS和吞吐量信息
命令:
iostat -d -k 1 1
输出:
[root@CT1186 ~]# iostat -d -k 1 1Linux 2.6.18-128.el5 (CT1186) 2012年12月28日
Device: tps kB_read/s kB_wrtn/s kB_read kB_wrtn
sda 22.72 21.85 243.71 337017916 3758984340
sda1 0.00 0.00 0.00 1329 268
sda2 0.11 1.87 1.76 28860797 27101108
sda3 0.98 0.31 8.75 4727086 135012508
sda4 0.00 0.00 0.00 3 0
sda5 6.95 0.06 54.37 962481 838566148
sda6 2.20 0.09 15.61 1418630 240744712
sda7 12.48 19.52 163.22 301047254 2517559596
说明:
tps:该设备每秒的传输次数(Indicate the number of transfers per second that were issued to the device.)。“一次传输”意思是“一次I/O请求”。多个逻辑请求可能会被合并为“一次I/O请求”。“一次传输”请求的大小是未知的。
kB_read/s:每秒从设备(drive expressed)读取的数据量;
kB_wrtn/s:每秒向设备(drive expressed)写入的数据量;
kB_read:读取的总数据量;kB_wrtn:写入的总数量数据量;
这些单位都为Kilobytes。
上面的例子中,我们可以看到磁盘sda以及它的各个分区的统计数据,当时统计的磁盘总TPS是22.73,下面是各个分区的TPS。(因为是瞬间值,所以总TPS并不严格等于各个分区TPS的总和)
实例3:查看设备使用率(%util)、响应时间(await)
命令:
iostat -d -x -k 1 1
输出:
[root@CT1186 ~]# iostat -d -x -k 1 1Linux 2.6.18-128.el5 (CT1186) 2012年12月28日
Device: rrqm/s wrqm/s r/s w/s rkB/s wkB/s avgrq-sz avgqu-sz await svctm %util
sda 0.44 38.59 0.40 22.32 21.85 243.71 23.37 0.04 1.78 4.20 9.54
sda1 0.00 0.00 0.00 0.00 0.00 0.00 18.90 0.00 8.26 6.46 0.00
sda2 0.36 0.43 0.11 0.01 1.87 1.76 63.57 0.01 63.75 1.94 0.02
sda3 0.00 1.24 0.04 0.95 0.31 8.75 18.42 0.04 39.77 8.73 0.86
sda4 0.00 0.00 0.00 0.00 0.00 0.00 2.00 0.00 19.67 19.67 0.00
sda5 0.00 6.65 0.00 6.94 0.06 54.37 15.67 0.26 36.81 4.48 3.11
sda6 0.00 1.71 0.01 2.19 0.09 15.61 14.29 0.03 12.40 5.84 1.28
sda7 0.08 28.56 0.25 12.24 19.52 163.22 29.28 0.27 21.46 5.00 6.25
说明:
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压力高)
另外 await 的参数也要多和 svctm 来参考.差的过高就一定有 IO 的问题.
avgqu-sz 也是个做 IO 调优时需要注意的地方,这个就是直接每次操作的数据的大小,如果次数多,但数据拿的小的话,其实 IO 也会很小.如果数据拿的大,才IO 的数据会高.也可以通过 avgqu-sz × ( r/s or w/s ) = rsec/s or wsec/s.也就是讲,读定速度是这个来决定的.
("也可以通过 avgqu-sz × ( r/s or w/s ) = rsec/s or wsec/s"
这个地方写错了。应该是
"avgrq-sz × ( r/s or w/s ) = rsec/s or wsec/s"
去年就看过这篇博文,今年再次搜到,终于有能力理解并去测试了…
开始以为avgrq-sz应该是read/write系统调用的 buffsize 决定的,测试之后发现不是这样,不知道跟硬件驱动是不是有关系?)
另外还可以参考
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 的速度和响应时间.
下面是别人写的这个参数输出的分析
1 2 3 4 5 6 |
# 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
|
上面的 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.
实例5
命令:iostat -d -x -k 1 1
输出:
[root@CT1186 ~]# iostat-d -x -k 1 1
Linux 2.6.18-128.el5(CT1186) 2013年08月23日
Device: rrqm/s wrqm/s r/s w/s rkB/s wkB/s avgrq-sz avgqu-sz await svctm %util
Sda 0.44 38.59 0.40 22.32 21.85 243.71 23.37 0.04 1.78 4.20 9.54
sda1 0.00 0.00 0.00 0.00 0.00 0.00 18.90 0.00 8.26 6.46 0.00
sda2 0.36 0.43 0.11 0.01 1.87 1.76 63.57 0.01 63.75 1.94 0.02
sda3 0.00 1.24 0.04 0.95 0.31 8.75 18.42 0.04 39.77 8.73 0.86
sda4 0.00 0.00 0.00 0.00 0.00 0.00 2.00 0.00 19.67 19.67 0.00
sda5 0.00 6.65 0.00 6.94 0.06 54.37 15.67 0.26 36.81 4.48 3.11
sda6 0.00 1.71 0.01 2.19 0.09 15.61 14.29 0.03 12.40 5.84 1.28
sda7 0.08 28.56 0.25 12.24 19.52 163.22 29.28 0.27 21.46 5.00 6.25
说明:
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的单位为毫秒)
形象的比喻:
r/s+w/s 类似于交款人的总数
平均队列长度(avgqu-sz)类似于单位时间里平均排队人的个数
平均服务时间(svctm)类似于收银员的收款速度
平均等待时间(await)类似于平均每人的等待时间
平均I/O数据(avgrq-sz)类似于平均每人所买的东西多少
I/O 操作率(%util)类似于收款台前有人排队的时间比例
设备IO操作:总IO(io)/s = r/s(读) +w/s(写) =1.46 + 25.28=26.74
平均每次设备I/O操作只需要0.36毫秒完成,现在却需要10.57毫秒完成,因为发出的请求太多(每秒26.74个),假如请求时同时发出的,可以这样计算平均等待时间:
平均等待时间=单个I/O服务器时间*(1+2+...+请求总数-1)/请求总数
每秒发出的I/0请求很多,但是平均队列就4,表示这些请求比较均匀,大部分处理还是比较及时。
针对用户给出数据进行分析
用户提供的iostat输出:
avg-cpu: %user %nice %system %iowait %steal %idle
0.03 0.00 0.03 6.74 0.00 93.19
Device: rrqm/s wrqm/s r/s w/s rMB/s wMB/s avgrq-sz avgqu-sz awaitsvctm %util
sda 0.00 198.00 0.50 135.00 0.00 1.27 19.25 1.16 8.58 7.34 99.45
sda1 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
sda2 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
sda3 0.00 198.00 0.50 135.00 0.00 1.27 19.25 1.16 8.58 7.34 99.45
had 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
参数说明:
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
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 值是 99.45 已经接近 100%,说明产生的I/O请求太多,I/O系统可能已经满负荷,该磁盘可能存在瓶颈。
同时参考 await 的值(8.58)和 svctm 值(7.34)比较接近,说明 I/O 几乎没有等待时间。svctm 一般要小于 await(因为同时等待的请求的等待时间被重复计算了),svctm 的大小一般和磁盘性能有关,CPU/内存的负荷也会对其有影响,请求过多也会间接导致 svctm 的增加。await 的大小一般取决于服务时间(svctm)以及 I/O 队列的长度和 I/O 请求的发出模式。
avgqu-sz 值是 1.16 ;是直接每次操作的数据的大小,如果次数多,但数据拿的小的话,其实 IO 也会很小。如果数据拿的大,那么IO 的数据才会高。队列长度(avgqu-sz)也可作为衡量系统 I/O 负荷的指标,但由于 avgqu-sz 是按照单位时间的平均值,所以不能反映瞬间的 I/O 洪水。
决议:
综合来看是磁盘写操作I/O请求过于频繁,建议考虑优化写算法。或者升级磁盘I/O。
实例4. Iostat –d –k 1 10
参数 -d 表示,显示设备(磁盘)使用状态;-k某些使用block为单位的列强制使用Kilobytes为单位;1 10表示,数据显示每隔1秒刷新一次,共显示10次。
tps:该设备每秒的传输次数(Indicate the number of transfers per second that were issued to the device.)。“一次传输”意思是“一次I/O请求”。多个逻辑请求可能会被合并为“一次I/O请求”。“一次传输”请求的大小是未知的。
kB_read/s:每秒从设备(drive expressed)读取的数据量;kB_wrtn/s:每秒向设备(drive expressed)写入的数据量;kB_read:读取的总数据量;kB_wrtn:写入的总数量数据量;这些单位都为Kilobytes。
rrqm/s:每秒这个设备相关的读取请求有多少被Merge了(当系统调用需要读取数据的时候,VFS将请求发到各个FS,如果FS发现不同的 读取请求读取的是相同Block的数据,FS会将这个请求合并Merge);wrqm/s:每秒这个设备相关的写入请求有多少被Merge了。
rsec/s:每秒读取的扇区数;wsec/:每秒写入的扇区数。r/s:The number of read requests that were issued to the device per second;w/s:The number of write requests that were issued to the device per second;
await:每一个IO请求的处理的平均时间(单位是微秒)。这里可以理解为IO的响应时间,一般地系统IO响应时间应该低于5ms,如果大于10ms就比较大了。
SVCTM:当前每个请求的平均处理时间,以MS位单位
%util:在统计时间内所有处理IO时间,除以总共统计时间。例如,如果统计间隔1秒,该设备有0.8秒在处理IO,而0.2秒闲置,那么该设 备的%util = 0.8/1 = 80%,所以该参数暗示了设备的繁忙程度。一般地,如果该参数是100%表示设备已经接近满负荷运行了(当然如果是多磁盘,即使%util是100%,因 为磁盘的并发能力,所以磁盘使用未必就到了瓶颈)。
公式: 每秒要求处理的请求数
(r/s+ws/)*await/1000ms
当前硬盘的超载比率
Avgqu_sz/(r/s+w/s)*100
一、 查看硬盘读取速度
命令:hdparm -t /dev/sda5
打印:Timing buffered disk reads: 254 MB in 3.01 seconds = 84.34 MB/sec
说明:能够指定具体的哪块硬盘进行查询的。
二、 查找最耗iowait的进程
操作步骤:
1. /etc/init.d/syslog stop
2. echo 1 > /proc/sys/vm/block_dump
3. dmesg | egrep "READ|WRITE|dirtied" | egrep -o '([a-zA-Z]*)' | sort | uniq -c | sort -rn | head
不要忘记在抓完之后关掉block_dump和启动syslog
4. echo 0 > /proc/sys/vm/block_dump
5. /etc/init.d/syslog start
iostat输出内容分析
在linux命令行中输入iostat,通常将会出现下面的输出:
[root@localhost ~]# iostat
Linux 5.14.0-284.11.1.el9_2.x86_64 (localhost.localdomain) 08/07/2023 _x86_64_ (4 CPU)
avg-cpu: %user %nice %system %iowait %steal %idle
0.31 0.01 0.44 0.02 0.00 99.22
Device tps kB_read/s kB_wrtn/s kB_dscd/s kB_read kB_wrtn kB_dscd
dm-0 3.19 72.63 35.90 0.00 202007 99835 0
dm-1 0.04 0.84 0.00 0.00 2348 0 0
nvme0n1 3.36 93.22 36.64 0.00 259264 101903 0
sr0 0.02 0.75 0.00 0.00 2096 0 0
首先第一行:
Linux 5.14.0-284.11.1.el9_2.x86_64 (localhost.localdomain) 08/07/2023 _x86_64_ (4 CPU)
1
Linux 5.14.0-284.11.1.el9_2.x86_64是内核的版本号,localhost.localdomain则是主机的名字, 08/07/2023当前的日期, _x86_64_是CPU的架构, (4 CPU)显示了当前系统的CPU的数量。
接着看第二部分,这部分是CPU的相关信息,其实和top命令的输出是类似的。
avg-cpu: %user %nice %system %iowait %steal %idle
0.31 0.01 0.44 0.02 0.00 99.22
1
2
cpu属性值说明:
%user:CPU处在用户模式下的时间百分比。
%nice:CPU处在带NICE值的用户模式下的时间百分比。
%system:CPU处在系统模式下的时间百分比。
%iowait:CPU等待输入输出完成时间的百分比。
%steal:管理程序维护另一个虚拟处理器时,虚拟CPU的无意识等待时间百分比。
%idle:CPU空闲时间百分比。
这里对iowait这个指标进行讲解,这个指标很容易被误解。
首先要有这样一个概念,%iowait是%idle的一个子集,其计算方法是这样的:
如果 CPU 此时处于 idle 状态,内核会做以下检查
1、是否存在从该 CPU 发起的一个未完成的本地磁盘IO请求
2、是否存在从该 CPU 发起的网络磁盘挂载的操作
如果存在以上任一情况,则 iowait 的计数器加 1,如果都没有,则 idle 的计数器加 1。
例如假如间隔时间是 1s,则共有 100 个时钟,假如 sys 计数为 2, user 计数为 3,ncie计数为0,iowait 计数为 1 ,steal计数为0, idle 计数为 94,则 它们的百分比依次为:2%、 %3、 0%、 1%、0%、94%。
知道了iowait的计算方法后,下面讲解一下iowait常见的一些误解:
iowait 表示等待IO完成,在此期间 CPU 不能接受其他任务
从上面 iowait 的定义可以知道,iowait 表示 CPU 处于空闲状态并且有未完成的磁盘 IO 请求,也就是说,iowait 的首要条件就是 CPU 空闲,既然空闲就能接受任务,只是当前没有可运行的任务,才会处于空闲状态的,为什么没有可运行的任务呢? 有可能是正在等待一些事件,比如:磁盘IO、键盘输入或者等待网络的数据等
iowait 高表示 IO 存在瓶颈
由于 Linux 文档对 iowait 的说明不多,这点很容易产生误解,iowait 第一个条件是 CPU 空闲,也即所有的进程都在休眠,第二个条件是 有未完成的 IO 请求。这两个条件放到一起很容易产生下面的理解:进程休眠的原因是为了等待 IO 请求完成,而 %iowait 变高说明进程因等待IO 而休眠的时间变长了,或者因等待IO而休眠的进程数量变多了 初一听,似乎很有道理,但实际是不对的。
iowait 升高并不一定会导致等待IO进程的数量变多,也不一定会导致等待IO的时间变长,我们借助下面的图来理解:
在这三张图的变化中,IO没有发生任何变化,仅仅是CPU的空闲时间发生了变化,iowait的值就发生了很大的变化,因此仅根据 %iowait 不能判断出IO存在瓶颈。
下面回到iostat,看第三部分的输出结果。
Device tps kB_read/s kB_wrtn/s kB_dscd/s kB_read kB_wrtn kB_dscd
dm-0 3.19 72.63 35.90 0.00 202007 99835 0
dm-1 0.04 0.84 0.00 0.00 2348 0 0
nvme0n1 3.36 93.22 36.64 0.00 259264 101903 0
sr0 0.02 0.75 0.00 0.00 2096 0 0
其每一列的含义如下所示:
Device:/dev 目录下的磁盘(或分区)名称
tps:该设备每秒的传输次数。一次传输即一次 I/O 请求,多个逻辑请求可能会被合并为一次 I/O 请求。一次传输请求的大小是未知的
kB_read/s:每秒从磁盘读取数据大小,单位KB/s
kB_wrtn/s:每秒写入磁盘的数据的大小,单位KB/s
kB_dscd/s: 每秒磁盘的丢块数,单数KB/s
kB_read:从磁盘读出的数据总数,单位KB
kB_wrtn:写入磁盘的的数据总数,单位KB
kB_dscd: 磁盘总的丢块数量
需要注意的是,如果使用iostat -dk 2这样的命令,每2s收集一次数据,则kB_wrtn的含义是2s内写入磁盘的数据总数,而kB_read的含义是2s内从磁盘读出的数据总数,kB_dscd的含义则是2s内磁盘块的丢块数量。
如果没有时间间隔参数,例如iostat -dk,则kB_wrtn的含义是从开机以来的写入磁盘的数据总量,kB_read的含义是从开机以来的从磁盘读出的数据总数,kB_dscd的含义则是开机以来的磁盘块的丢块数量。
除此以外,iostat 可以使用-x输出一些扩展列,例如下面的输出:
Device r/s rkB/s rrqm/s %rrqm r_await rareq-sz w/s wkB/s wrqm/s %wrqm w_await wareq-sz d/s dkB/s drqm/s %drqm d_await dareq-sz f/s f_await aqu-sz %util
dm-0 2.16 47.69 0.00 0.00 0.56 22.06 0.88 25.70 0.00 0.00 2.66 29.16 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.25
dm-1 0.02 0.49 0.00 0.00 0.30 23.72 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 0.00 0.00 0.00
nvme0n1 2.28 59.76 0.01 0.38 0.54 26.18 0.74 26.13 0.15 17.11 1.89 35.12 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.26
sr0 0.01 0.44 0.00 0.00 0.56 38.81 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 0.00 0.00 0.00
读指标:
r/s:每秒向磁盘发起的读操作数
rkB/s:每秒读K字节数
rrqm/s:每秒这个设备相关的读取请求有多少被Merge了(当系统调用需要读取数据的时候,VFS将请求发到各个FS,如果FS发现不同的读取请求读取的是相同Block的数据,FS会将这个请求合并Merge);
%rrqm: 合并读请求占的百分比
r_await:每个读操作平均所需的时间;不仅包括硬盘设备读操作的时间,还包括了在kernel队列中等待的时间
rareq-sz:平均读请求大小
写指标:
w/s:每秒向磁盘发起的写操作数
wkB/s:每秒写K字节数
wrqm/s:每秒这个设备相关的写入请求有多少被Merge了。
%wrqm:合并写请求占的百分比
w_await:每个写操作平均所需的时间;不仅包括硬盘设备写操作的时间,还包括了在kernel队列中等待的时间
wareq-sz:平均写请求大小
抛弃指标:
d/s:每秒设备完成的抛弃请求数(合并后)。
dkB/s:从设备中每秒抛弃的kB数量
drqm/s: 每秒排队到设备中的合并抛弃请求的数量
%drqm:抛弃请求在发送到设备之前已合并在一起的百分比。
d_await: 发出要服务的设备的抛弃请求的平均时间(以毫秒为单位)。 这包括队列中的请求所花费的时间以及为请求服务所花费的时间。
dareq-sz: 发出给设备的抛弃请求的平均大小(以千字节为单位)。
其他指标:
aqu-sz:平均请求队列长度
%util: 一秒中有百分之多少的时间用于 I/O 操作,即被io消耗的cpu百分比,向设备发出I/O请求的经过时间百分比(设备的带宽利用率)。当串行服务请求的设备的该值接近100%时,将发生设备饱和。 但是对于并行处理请求的设备(例如RAID阵列和现代SSD),此数字并不反映其性能限制。这个指标高说明IO基本上就到瓶颈了,但是低也不一定IO就不是瓶颈。一般%util大于70%,I/O压力就比较大. 同时可以结合vmstat查看查看b参数(等待资源的进程数)和wa参数(I/O等待所占用的CPU时间的百分比,高过30%时I/O压力高)
实际测试案列
在测试时,使用dd命令来模拟磁盘的读写
dd if=/dev/zero of=./a.dat bs=8k count=1M oflag=direct
1
if=文件名:输入文件名,默认为标准输入。即指定源文件。
of=文件名:输出文件名,默认为标准输出。即指定目的文件。
bs=bytes:同时设置读入/输出的块大小为bytes个字节。
count=blocks:仅拷贝blocks个块,块大小等于ibs指定的字节数。
上述命令将向a.dat文件中写入8G的数据。
打开另一个窗口,使用iostat进行监控。
首先看看iostat -kx 1的数据。
从wkB指标得知,现在磁盘的写入速度在70M左右。从%util指标得知,目前磁盘的使用率已经高达100%,满负荷运行。此时iowait的值为15%左右。
再看看iostat -dk 1的输出:
从kB_read/s指标得知,目前磁盘的写入速度在70M左右。
参考:https://blog.csdn.net/qq_31442743/article/details/132278407