解释/ proc / diskstats中的读取,写入和总IO时间

我注意到,当我看到/proc/diskstats的输出时,花费在阅读上的总时间,写入的总时间和执行IO的总时间之间存在差异。 例如,我在/proc/diskstats中看到一个条目:

 $ cat /proc/diskstats ... 8 0 sda 944150584 590524 235547588959 780672196 833280352 534699043 322507689696 3472000824 1 812190100 4246357772 ... 

根据https://www.kernel.org/doc/Documentation/iostats.txt的文档,

字段4 – 读取的毫秒数这是所有读取花费的总毫秒数(从__make_request()到end_that_request_last())。

字段8 – 写入毫秒数这是所有写入所花费的总毫秒数(从__make_request()到end_that_request_last())的测量值。

字段10 – 执行I / O所花费的毫秒数只要字段9非零,此字段就会增加。

因此,我认为第十个领域将是第四个和第八个领域的总和,因为我认为总的IO时间是阅读时间和写作时间的总和。 但是,我从来没有注意到这种情况,而且我一直观察到第四和第八场的总和大于第十场(例如,在上面的行(780672196 + 3472000824 – 812190100 =我想知道如果有人能解释为什么这些数字是不同的,似乎第十个领域是试图捕捉一些不同于第四和第八领域的总和。

我没有看过源代码,但似乎不同源于两种不同的会计模式。

#4和#8字段总结了每个请求完成的时间。 这意味着并行发出的请求仍然有助于增加计数。

#10字段只计算实际的队列和磁盘繁忙时间,因此它们将并行发出的请求计为单个请求。

举一个实际的例子。 在/boot分区上,我dd MB文件。 看一下统计数据:

 [root@localhost boot]# cat /proc/diskstats | grep sda1 8 1 sda1 46256 0 255703 19332 2063 0 4162 538 0 11207 19862 [root@localhost boot]# dd if=initramfs-0-rescue-7dc32e3935ba4ce1ae50a0a8170e4480.img of=/dev/null 84099+1 records in 84099+1 records out 43058701 bytes (43 MB) copied, 0.347783 s, 124 MB/s [root@localhost boot]# cat /proc/diskstats | grep sda1 8 1 sda1 46342 0 339807 23011 2063 0 4162 538 0 11551 23540 [root@localhost boot]# 

读取文件需要〜0.35s,或〜350ms。 然而,计数器#4和#10的反应却大不相同:首先增加了大约4000,而后者只增加了大约350.很容易看出哪个具有“正确”的价值:就像我们所知的那样, dd ,整个操作花费了大约350毫秒,10号场增加了相同的数量。

那么,为什么4号场增加了这么多,以及它真正衡量的是什么呢?

首先,让我们了解请求级别正在发生的事情。 dd默认使用512B的请求,但是linux的pagecache在4KB的粒度下工作,所以我们应该期待大约1000 x 4KB的请求。 这1000个请求被放入一个队列中,并逐一发出(为了简单起见,让我们假装NCQ不存在)并分派到磁盘。 由于机械磁盘在连续读取方面相当出色,他们通常使用预读策略 – 即:读取的数据多于所需数据。 这意味着,在第一个4K请求完成之后,所有其他后续请求将在很短的时间内被服务。

让我们来做一些math运算,

  • 请求数:1000(全部请求同时进入队列)
  • 第一次请求完成时间:4ms
  • 时间为所有后续请求完成:0ms(是的,我告诉你这是一个疯狂的 semplification)

总请求时间以字段#4来衡量:1000个入队请求* 4ms 每个 == 4000ms。 这大概是#4场增加的价值…

底线:

  • 字段#4和#8测量从单个请求的angular度来服务I / O请求所花费的时间,将其乘以请求号码
  • #10字段会告诉您在I / Opath中使用的实际stream逝时间(“挂钟”)

绘制一个approssimative并行:思考多核CPU。 两个进程可以同时敲击CPU,每个执行60秒。 使用的总CPU时间为120s(60s * 2),但实际的时间总计保持在60s,因为两个进程同时运行。