您的位置:首页 > 移动开发 > IOS开发

IOSTAT中关于%util,svctm存在的陷阱及解决办法

2015-08-06 17:34 465 查看
在写瓶颈确认之IO瓶颈确认之第一篇这篇博客以前,自认为对IO情况确认还是没问题的。

在写博客时,对以前理解并不确切的地方进行了深入了解。 在经过理解后,发现之前并不是不确切,而是有部分理解错误的地方,现在特意在上一篇的基础上整改一篇出来,而不是进行直接在原基础修改,就是希望可以给大家提个醒,也给自己提个醒。

重点提示:实时看到的util%和svctm全部都不可取

------------------iostat -x 每项内容解释 可在上面所述blog中查看--

Device:         rrqm/s   wrqm/s   r/s   w/s   rsec/s   wsec/s avgrq-sz avgqu-sz   await  svctm  %util
sdb1              0.01     0.44  0.24  0.57     3.44     8.14    14.34     0.00    2.28   0.66   0.05

r/s + w/s:  就是当前的IOPS

avgrq-sz:就是当前每秒平均吞吐量 单位是扇区(512b)

await:请求队列中等待时间+svctm(服务时间)     单位是毫秒,按照每次IO平均。

svctm:IO平均服务时间

          服务时间包括:磁头寻道时间(目前平均为3毫秒)+旋转延迟时间(磁盘转速相关)+数据传输时间(简单计算时可忽略不计)

                                   旋转延迟时间详解:一般以旋转一周时间的1/2表示

                                                                       7200转的为 60/7200/2 =0.00416666..秒=4.17毫秒

                                                                      15000转为   60/15000/2=0.002秒=2毫秒

%util:之前最大的误解,错误观点 100%就是磁盘已经完全繁忙了,其实并不是。

             机械硬盘,在物理层面是串行的,既是一个时间只能干一个活,虽然有各种级别的concurrency,但并不是真正的并行。

             SSD,RAID 则不同。是可以真正在物理层面上并行执行多个IO。可以一个时间物理执行多个IO

            %util的计算 有一个简单的算法:concurrency = (r/s + w/s) * (svctm / 1000)
                          %util = concurrency * 100%

                                                                      然而这个concurrency  是个伪命题,因为svctm也是通过计算而来的,

                                                                     无论怎样压,算出来的concurrency都是1左右,那么自然util% 乘以出来就是100%

 举例说明:

记录一个快递员的繁忙程度(uti%)是通过看这个 快递员在一定时间内,真正用于工作的时间是多少。

统计时间为10分钟,那么10分钟内 快递员一口水都没喝,都在跑来跑去忙活。那么我们可以认为繁忙率是100%

这就是util%的计算方法。这种方法在单块机械磁盘(串行IO)的时候没有任何问题。

技术在进步,出现了SSD以及RAID后,我们就可以并行的执行IO,举例如下:

这个快递员是漩涡鸣人,会分身术,其实它可以分出15个分身,一起出去送快递。

但原本的算法,只盯着 漩涡鸣人 本身,10分钟内跑来跑去,就认为他100%繁忙

其实他真正的百分百繁忙,是 本身+15个分身,总计16个漩涡鸣人 全部跑来跑去送快递,一口水不喝。

因为util%算法的局限性,在快递员会分身术后,就已经完全不准确了。

 通过如上描述我们知道,以前通过查看%util来确认压力是否大已经非常不可取了

 在sysstat网站的最新文档中也已经注明: But for devices serving requests in parallel, such as RAID arrays and modern SSDs, this number does not reflect
their performance limits.  文档地址:http://sebastien.godard.pagesperso-orange.fr/man_iostat.html

结论1:util%到达100% 并不代表使用率真的到达百分百

在sysstat最新文档中,svctm已经被注明不可信,因为iostat各值大都是被计算出来的,而svctm计算方法存在错误的地方,参考:http://www.xaprb.com/blog/2010/09/06/beware-of-svctm-in-linuxs-iostat/               

结论2:实时查看的svctm已经不可取,因为它并不代表真正的存储service time,因为它是计算出来的。

验证结论1和结论2
请查看下面两个iostat -x的内容,是在同一个SSD盘上压测出来的结果
压测命令:
fio -filename=/dev/sdb1 -direct=1 -iodepth 1 -rw=randread -ioengine=sync -bs=8k -numjobs=1 -runtime=60 -group_reporting -name=mytest -norandommap

-numjobs=1 代表开启IO的进程为1,
-iodepth 1    
-ioengine=sync  同步IO模式
A结果:
avg-cpu:  %user   %nice %system %iowait  %steal   %idle
8.04    0.00   14.57   27.14    0.00   50.25

Device:         rrqm/s   wrqm/s   r/s   w/s   rsec/s   wsec/s avgrq-sz avgqu-sz   await  svctm  %util
sda               0.00     0.00  0.00  0.00     0.00     0.00     0.00     0.00    0.00   0.00   0.00
.
.
.
sdb1              0.00     0.00 1416.00  0.00 22656.00     0.00    16.00     0.86    0.61   0.61  100.00


压测命令:
 fio -filename=/dev/sdb1 -direct=1 -iodepth 32 -rw=randread -ioengine=libaio -bs=8k -numjobs=2 -runtime=60 -group_reporting -name=mytest2 -norandommap

-numjobs=2 开启IO的进程为2

-iodepth=32
-ioengine=libaio  (linux本身采用的异步IO模式)
B结果:
Device:         rrqm/s   wrqm/s   r/s   w/s   rsec/s   wsec/s avgrq-sz avgqu-sz   await  svctm  %util
sda               7.00     0.00 20.00  0.00  1360.00     0.00    68.00     0.06    3.15   2.90   5.80
.
.
.
sdb1              0.00     0.00 9342.00  0.00 149472.00     0.00    16.00     9.21    0.99   0.11 100.10


结论2:实时查看的svctm已经不可取,因为它并不代表真正的存储service time,因为它是计算出来的。
验证:同一块磁盘,我们通过不同的压测方式,竟然得到不同的svctm,而service time原本意义是不可变,固定的IO耗时

结论1:util%到达100%
并不代表使用率真的到达百分百

验证:A结果 ,IOPS到1416,util%就已经到达100%
            B结果 ,IOPS到9342,util%还是100%

---------------------------------------------------------------------------------解决办法-----------------------------------------------
问题1:我们怎样获得真正的serviice time(svctm)?
这里提供给大家一个得到真正svctm的办法
我们可以通过fio等压测工具,通过设置为同步IO,仅设置一个线程,以及io_depth也设置为1,压测出来的就是真正的service time(svctm),如果结果1

问题2:我们怎样获得某磁盘或lun的io最大并行度、及如何获得真正的util%使用率?
            最大并行度 =
压测满(r/s + w/s) * (真实svctm
/ 1000)
   
%util = concurrency * 100%

计算公式依然是上面所提那个简单的公式,但是增加几个标签,如压测满,如真实

我们通过结果B,进行计算 最大并行度
结果B 就是我这块SSD的压满后的结果
结果A 的svctm就是真实的service time,带入公式
最大并行度 = (9342+0) *
(0.61 / 1000) =5.63762

当前磁盘真正的繁忙百分百为 5.53762*100=563.742%
我们可以通过写小工具,调用iostat -x的结果,并且将svctm 替换,就可以算出真实的util%时间

算出真实的最大并行度有什么用?

当util% ,svctm 都不准确时,我们应该如何通过原始的iostat -x 判断繁忙度?

我们这里应该参考avgqu-sz:超过处理能力的请求数目,待处理的 I/O 请求,当请求持续超出磁盘处理能力,该值将增加。

 
                              网上标准说持续超过2就应该警示,具体值大家在工作中自己摸索

 
                              具体指什么,如一块机械盘,串行IO(每次1个IO),那么avgqu-sz持续大于2既代表持续有两倍读写能力的IO请求在等待。

 
                              那么当RAIDs 或者 SSD等并行,这里假定并行度为5.63,那么 avgqu-sz持续大于10,才代表持续有两倍读写能力的IO请求在等待。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: