关于服务器IO监控的了解

可以分为

  • 繁忙程度 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监控。因此,并不能依赖某个特定的指标,持续性的收集数据,观察数据的波动性,是比较可靠的办法的。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,607评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,047评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,496评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,405评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,400评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,479评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,883评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,535评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,743评论 1 295
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,544评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,612评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,309评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,881评论 3 306
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,891评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,136评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,783评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,316评论 2 342