美文网首页
关于服务器IO监控的了解

关于服务器IO监控的了解

作者: 达恰里 | 来源:发表于2018-08-06 13:02 被阅读0次

可以分为

  • 繁忙程度 util

  • 响应速度 await

获取数据

/proc/diskstats

以Linux为例,该服务器上有一块vda设备,该vda设备的diskstats如下

root@iZj6c9cop51kep9kwnw7p1Z:~# cat /proc/diskstats | grep vda

253      0 vda 656666 270 16523794 2344432 3339086 2233028 63578608 7583352 0 784384 9927392

253      1 vda1 656583 270 16519674 2344040 3300685 2233028 63578608 7563340 0 764820 9906996

前三位是设备相关标识。从第四位开始到第七位是读相关,第八位到第十一位是写相关,后三位分别是IO等待、处理IO时间、处理IO加权时间。

4:rd_ios 读操作的次数。

5:rd_merges 合并读操作的次数。如果两个读操作读取相邻的数据块时,可以被合并成一个,以提高效率。合并的操作通常是I/O scheduler(也叫elevator)负责的。

6:rd_sectors 读取的扇区数量。

7:rd_ticks 读操作消耗的时间(以毫秒为单位)。每个读操作从__make_request()开始计时,到end_that_request_last()为止,包括了在队列中等待的时间。

8:wr_ios 写操作的次数。

9:wr_merges 合并写操作的次数。

10:wr_sectors 写入的扇区数量。

11:wr_ticks 写操作消耗的时间(以毫秒为单位)。

12:in_flight 当前未完成的I/O数量。在I/O请求进入队列时该值加1,在I/O结束时该值减1,是I/O请求进入队列时,而不是提交给硬盘设备时。

13:io_ticks 该设备用于处理I/O的自然时间(wall-clock time)。

14:time_in_queue 对字段io_ticks的加权值。字段io_ticks是自然时间,不考虑当前有几个I/O,而time_in_queue是用当前的I/O数量(即in_flight)乘以自然时间。虽然该字段的名称是time_in_queue,但并不真的只是在队列中的时间,其中还包含了硬盘处理I/O的时间。iostat在计算avgqu-sz时会用到这个字段。

请注意io_ticks与rd_ticks和wr_ticks的区别,rd_ticks和wr_ticks是把每一个I/O所消耗的时间累加在一起,因为硬盘设备通常可以并行处理多个I/O,所以rd_ticks和wr_ticks往往会比自然时间大。而io_ticks表示该设备有I/O(即非空闲)的时间,不考虑I/O有多少,只考虑有没有。在实际计算时,in_flight不为零的时候io_ticks保持计时,字段#9(in_flight)为零的时候io_ticks停止计时。

iostat

在Linux上执行命令,得到信息如下

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的信息是通过获取两次/proc/diskstats上的信息然后计算得出的。

注:下面的公式中“Δ”表示两次取样之间的差值,“Δt”表示采样周期。

tps:每秒I/O次数=[(Δrd_ios+Δwr_ios)/Δt]

r/s:每秒读操作的次数=[Δrd_ios/Δt]

w/s:每秒写操作的次数=[Δwr_ios/Δt]

rkB/s:每秒读取的千字节数=[Δrd_sectors/Δt]*[512/1024]

wkB/s:每秒写入的千字节数=[Δwr_sectors/Δt]*[512/1024]

rrqm/s:每秒合并读操作的次数=[Δrd_merges/Δt]

wrqm/s:每秒合并写操作的次数=[Δwr_merges/Δt]

avgrq-sz:每个I/O的平均扇区数=[Δrd_sectors+Δwr_sectors]/[Δrd_ios+Δwr_ios]

avgqu-sz:平均未完成的I/O请求数量=[Δtime_in_queue/Δt]

(手册上说是队列里的平均I/O请求数量,更恰当的理解应该是平均未完成的I/O请求数量。)

await:每个I/O平均所需的时间=[Δrd_ticks+Δwr_ticks]/[Δrd_ios+Δwr_ios]

(不仅包括硬盘设备处理I/O的时间,还包括了在kernel队列中等待的时间。)

r_await:每个读操作平均所需的时间=[Δrd_ticks/Δrd_ios]

不仅包括硬盘设备读操作的时间,还包括了在kernel队列中等待的时间。

w_await:每个写操作平均所需的时间=[Δwr_ticks/Δwr_ios]

不仅包括硬盘设备写操作的时间,还包括了在kernel队列中等待的时间。

%util:该硬盘设备的繁忙比率=[Δio_ticks/Δt]

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

psutil

这是一个python的第三方库,也可以获取IO的信息。

In [22]: import psutil

In [23]: psutil.disk_io_counters()

Out[23]: sdiskio(read_count=674028, write_count=3374706, read_bytes=8607638528, write_bytes=33387319296, read_time=2446400, write_time=7583480, read_merged_count=270, write_merged_count=2330676, busy_time=783312)

计算数据

iostat是通过/proc/diskstats中的数据进行计算。而psutil也是获取的/rpc/diskstats中的数据,所以理论上我们是可以通过psutil模拟出iostat的功能。

回到开头,我们先计算磁盘繁忙程度,util。大概的公式如下。实际上,这个util并不能准确的相信,仅供参考,而判断磁盘繁忙程度,目前尚未找到比较好的方法。

In [30]: import time

In [31]: a = time.time()

In [32]: abt = psutil.disk_io_counters()[8]



In [33]: time.sleep(1)

In [34]: b = time.time()

In [35]: bbt = psutil.disk_io_counters()[8]

In [36]: (bbt-abt)/(b-a)

Out[36]: 0.44979996398143424

%util表示该设备有I/O(即非空闲)的时间比率,不考虑I/O有多少,只考虑有没有。由于现代硬盘设备都有并行处理多个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(1)有没有哪个指标可以衡量硬盘设备的饱和程度呢?很遗憾,没有。

接下来我们计算磁盘响应速度,await。大概公式如下。和util一样,并不是一个可以完全相信的指标,而且硬盘与硬盘之间差异很大。仅作参考。

n [43]: a = time.time()

In [44]: ap = psutil.disk_io_counters()

In [45]: time.sleep(1)

In [46]: b = time.time()

In [47]: bp = psutil.disk_io_counters()

In [48]: ((bp[4]-ap[4])/(b-a) + (bp[5]-ap[5])/(b-a))/((bp[0]-ap[0])/(b-a) + (bp[1]-ap[1])/(b-a))

Out[48]: 0.14285714285714285

await是单个I/O所消耗的时间,包括硬盘设备处理I/O的时间和I/O请求在kernel队列中等待的时间,正常情况下队列等待时间可以忽略不计,姑且把await当作衡量硬盘速度的指标吧,那么多大算是正常呢?

对于SSD,从0.0x毫秒到1.x毫秒不等,具体看产品手册;

对于机械硬盘,可以参考以下文档中的计算方法:

http://cseweb.ucsd.edu/classes/wi01/cse102/sol2.pdf

大致来说一万转的机械硬盘是8.38毫秒,包括寻道时间、旋转延迟、传输时间。

在实践中,要根据应用场景来判断await是否正常,如果I/O模式很随机、I/O负载比较高,会导致磁头乱跑,寻道时间长,那么相应地await要估算得大一些;如果I/O模式是顺序读写,只有单一进程产生I/O负载,那么寻道时间和旋转延迟都可以忽略不计,主要考虑传输时间,相应地await就应该很小,甚至不到1毫秒。

最后

通过反复查找资料和搜索相关信息,都没有找到一个比较好的方法进行磁盘IO监控。因此,并不能依赖某个特定的指标,持续性的收集数据,观察数据的波动性,是比较可靠的办法的。

相关文章

网友评论

      本文标题:关于服务器IO监控的了解

      本文链接:https://www.haomeiwen.com/subject/svgwvftx.html