代码改变世界

iostat命令详解

2022-01-18 16:57  清风软件测试开发  阅读(1365)  评论(0编辑  收藏  举报

iostat命令详解

iostat 主要是统计 磁盘活动情况。

iostat有以下缺陷:

iostat的输出结果大多数是一段时间内的平均值,因此难以反映峰值情况
iostat仅能对系统整体情况进行分析汇报,却不能针对某个进程进行深入分析。
iostat未单独统计IO处理信息,而是将IO处理时间和IO等待时间合并统计,因此包括await在内的指标并不能非常准确地衡量磁盘性能表现。

 

iostat -d -k 2

参数 -d 表示,显示设备(磁盘)使用状态;-k某些使用block为单位的列强制使用Kilobytes为单位;2表示,数据显示每隔2秒刷新一次。

输出如下

复制代码
iostat -d -k 1 10
Device:            tps    kB_read/s    kB_wrtn/s    kB_read    kB_wrtn
sda              39.29        21.14         1.44  441339807   29990031
sda1              0.00         0.00         0.00       1623        523
sda2              1.32         1.43         4.54   29834273   94827104
sda3              6.30         0.85        24.95   17816289  520725244
sda5              0.85         0.46         3.40    9543503   70970116
sda6              0.00         0.00         0.00        550        236
sda7              0.00         0.00         0.00        406          0
sda8              0.00         0.00         0.00        406          0
sda9              0.00         0.00         0.00        406          0
sda10            60.68        18.35        71.43  383002263 1490928140

Device:            tps    kB_read/s    kB_wrtn/s    kB_read    kB_wrtn
sda             327.55      5159.18       102.04       5056        100
sda1              0.00         0.00         0.00          0          0
复制代码

输出信息的意义

tps:该设备每秒的传输次数。"一次传输"意思是"一次I/O请求"。多个逻辑请求可能会被合并为"一次I/O请求"。"一次传输"请求的大小是未知的。

kB_read/s:每秒从设备(drive expressed)读取的数据量;
kB_wrtn/s:每秒向设备(drive expressed)写入的数据量;
kB_read:读取的总数据量; kB_wrtn:写入的总数量数据量;这些单位都为Kilobytes。

上面的例子中,我们可以看到磁盘sda以及它的各个分区的统计数据,当时统计的磁盘总TPS是39.29,下面是各个分区的TPS。(因为是瞬间值,所以总TPS并不严格等于各个分区TPS的总和)

 

指定监控的设备名称为sda,该命令的输出结果和上面命令完全相同。

 iostat -d sda 2

默认监控所有的硬盘设备,现在指定只监控sda。 

 

-x 参数

iostat还有一个比较常用的选项-x,该选项将用于显示和io相关的扩展数据。

iostat -d -x -k 1 10
Device:    rrqm/s wrqm/s   r/s   w/s  rsec/s  wsec/s    rkB/s    wkB/s avgrq-sz avgqu-sz   await  svctm  %util
sda          1.56  28.31  7.80 31.49   42.51    2.92    21.26     1.46     1.16     0.03    0.79   2.62  10.28
Device:    rrqm/s wrqm/s   r/s   w/s  rsec/s  wsec/s    rkB/s    wkB/s avgrq-sz avgqu-sz   await  svctm  %util
sda          2.00  20.00 381.00  7.00 12320.00  216.00  6160.00   108.00    32.31     1.75    4.50   2.17  84.20

 

输出信息的含义

复制代码
rrqm/s:每秒合并读操作的次数,如果两个读操作读取相邻的数据块时,可以被合并成一个,以提高效率。合并的操作通常是I/O scheduler(也叫elevator)负责的。每秒这个设备相关的读取请求有多少被Merge了(当系统调用需要读取数据的时候,VFS将请求发到各个FS,如果FS发现不同的读取请求读取的是相同Block的数据,FS会将这个请求合并Merge);
wrqm/s:每秒这个设备相关的写入请求有多少被Merge了。 rsec/s:每秒读取的扇区数; wsec/:每秒写入的扇区数。

  rKB/s:每秒读取的字节数(KB)

  wKB/s:每秒写入的字节数(KB)

avgrq-sz 平均请求扇区的大小
avgqu-sz 是平均请求队列的长度。毫无疑问,队列越短越好。    
await:  每一个IO请求的处理的平均时间(单位是微秒毫秒)。这里可以理解为IO的响应时间,一般地系统IO响应时间应该低于5ms,如果大于10ms就比较大了。
         这个时间包括了队列时间服务时间,也就是说,一般情况下,await大于svctm,它们的差值越小,则说明队列时间越短,反之差值越大,队列时间越长,说明系统出了问题。

           r_await:每个读操作平均所需要的时间,包括硬盘设备读操作的时间,也包括在内核队列中的时间。

       w_wait:每个写操平均所需要的时间,包括硬盘设备写操作的时间,也包括在队列中等待的时间。

svctm    表示平均每次设备I/O操作的服务时间(以毫秒为单位)。如果svctm的值与await很接近,表示几乎没有I/O等待,磁盘性能很好如果await的值远高于svctm的值,则表示I/O队列等待太长,系统上运行的应用程序将变慢。
%util: 在统计时间内所有处理IO时间,除以总共统计时间。例如,如果统计间隔1秒,该设备有0.8秒在处理IO,而0.2秒闲置,那么该设备的%util = 0.8/1 = 80%,所以该参数暗示了设备的繁忙程度
。一般地,如果该参数是100%表示设备已经接近满负荷运行了(当然如果是多磁盘,即使%util是100%,因为磁盘的并发能力,所以磁盘使用未必就到了瓶颈)。
复制代码

 

深入解析
avgqu-sz

IO请求的队列长度,反映了系统磁盘任务处理的繁忙程度,该值越大,表示排队等待处理的IO请求越多
平均队列长度的计算:
我们考虑如下的场景,如果同一时间来了250个IO请求,后续再也没有新的请求到来。这种情况下,每个请求处理时间都是4ms,那么所有IO的平均等待时间为:

平均等待时间 = 单个请求处理时间*(1+2+3+4...+(请求总数-1))/请求总数

对于我们的例子来说,平均等待时间是 500ms,那么所有IO花费的总时间为250*500 = 125000ms,这个时间除以1000ms,得到 125,即平均队列长度。
这个值很明显是符合直观的。排在队列最前端的IO认为,队列的长度是0,第2个IO认为队列的长度是1,第3个IO认为队列的长度是2,最后一个认为队列的长度是249。

await

await是单个I/O所消耗的时间,包括硬盘设备处理I/O的时间和I/O请求在kernel队列中等待的时间:

await = IO 平均处理时间 + IO在队列的平均等待时间

正常情况下队列等待时间可以忽略不计:

await = ((所有读IO的时间)+(所有写IO的时间))/((读请求的个数) + (写请求的个数))

这个值,多大算正常呢?
对于SSD,从0.0x毫秒到1.x毫秒不等,具体看产品手册。
对于机械硬盘,大致来说一万转的机械硬盘是8.38毫秒,包括寻道时间、旋转延迟、传输时间。
关于await的一个误区是,人们常常武断地认为,await值比较高,就认为磁盘性能差,其实,await这个值不能反映硬盘设备的性能。
我们考虑两种IO的模型:

250个IO请求同时进入等待队列
250个IO请求依次发起,待上一个IO完成后,发起下一个IO
第一种情况await高达500ms,第二个情况await只有4ms,但是都是同一块盘。
在实践中,要根据应用场景来判断await是否正常,如果I/O模式很随机、I/O负载比较高,会导致磁头乱跑,寻道时间长,那么相应地await要估算得大一些如果I/O模式是顺序读写,只有单一进程产生I/O负载,那么寻道时间和旋转延迟都可以忽略不计,主要考虑传输时间,相应地await就应该很小,甚至不到1毫秒。
对磁盘阵列来说,因为有硬件缓存,写操作不等落盘就算完成,所以写操作的service time大大加快了,如果磁盘阵列的写操作不在一两个毫秒以内就算慢的了;读操作则未必,不在缓存中的数据仍然需要读取物理硬盘,单个小数据块的读取速度跟单盘差不多。

%util

%util表示该设备有I/O(即非空闲)的时间比率,不考虑I/O有多少,只考虑有没有。

很多初学者看到%util 等于100%就说硬盘能力到顶了,这种说法是错误的。

由于现代硬盘设备都有并行处理多个I/O请求的能力,所以%util即使达到100%也不意味着设备饱和了,举个简化的例子:

某硬盘处理单个I/O需要0.1秒,有能力同时处理10个I/O请求。
当10个I/O请求依次顺序提交的时候,需要1秒才能全部完成,在1秒的采样周期里%util达到100%。
而如果10个I/O请求一次性提交的话,0.1秒就全部完成,在1秒的采样周期里%util只有10%。
可见,即使%util高达100%,硬盘也仍然有可能还有余力处理更多的I/O请求,即没有达到饱和状态。那么iostat有没有哪个指标可以衡量硬盘设备的饱和程度呢?很遗憾,没有。

 

实例分析

复制代码
iostat -d -k 1 |grep sda10
Device:            tps    kB_read/s    kB_wrtn/s    kB_read    kB_wrtn
sda10            60.72        18.95        71.53  395637647 1493241908
sda10           299.02      4266.67       129.41       4352        132
sda10           483.84      4589.90      4117.17       4544       4076
sda10           218.00      3360.00       100.00       3360        100
sda10           546.00      8784.00       124.00       8784        124
sda10           827.00     13232.00       136.00      13232        136
复制代码

上面看到,磁盘每秒传输次数平均约400;每秒磁盘读取约5MB,写入约1MB。

 

iostat -d -x -k 1
Device:    rrqm/s wrqm/s   r/s   w/s  rsec/s  wsec/s    rkB/s    wkB/s   avgrq-sz  avgqu-sz   await  svctm  %util
sda          1.56  28.31  7.84 31.50   43.65    3.16    21.82     1.58      1.19      0.03    0.80   2.61   10.29
sda          1.98  24.75 419.80  6.93 13465.35  253.47  6732.67   126.73    32.15     2.00    4.70   2.00   85.25
sda          3.06  41.84 444.90 54.08 14204.08 2048.98  7102.04  1024.49    32.57     2.10    4.21   1.85   92.24

可以看到磁盘的平均响应时间await<5ms,磁盘使用率%util>80,avgqu-sz出现了等待处理的io,表明磁盘响应正常,但是已经很繁忙了。