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

解释 /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 = 3440482920)。我想知道是否有人可以解释为什么这些数字不同,似乎第十个字段试图捕获与第四个和第八个字段的总和不同的东西。

答案1

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

#4 和 #8 字段对时间求和每个请求需要完成。这意味着并行发出的请求仍然会促使计数增长。

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

让我们举一个实际的例子。按/boot分区,我有dd一个~4 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.35 秒,即约 350 毫秒。但是,计数器 #4 和 #10 的反应方式截然不同:前者增加了约 4000,而后者仅增加了约 350。很容易看出哪个具有“正确”的值:它是字段 #10,因为我们知道dd整个操作大约需要 350 毫秒,而字段 #10 也增加了相同的量。

那么,为什么字段#4增加这么多,以及它真正衡量的是什么?

首先,让我们了解请求级别发生了什么。dd默认情况下,使用 512B 请求,但 Linux 页面缓存以 4KB 的粒度工作,因此我们应该预期大约 1000 x 4KB 请求。这 1000 个请求被放入队列并逐个发出(为简单起见,我们假设 NCQ 不存在)并分派到磁盘。由于机械磁盘在顺序读取方面相当出色,因此它们通常使用预读策略 - 即:它们读取的数据多于所需。这意味着,在第一个 4K 请求完成后,所有其他后续请求将在很短的时间内得到处理。

让我们做一些数学运算,并进行简单的简化:

  • 请求数:1000(所有请求同时进入队列)
  • 第一个请求完成的时间:4ms
  • 的时间全部后续请求完成时间:0ms(是的,我告诉过你这是荒野簡化)

总请求时间由字段 #4 衡量:1000 个队列内请求 * 4ms每个== 4000 毫秒。这大致是字段 #4 增加的值……

底线:

  • 字段 #4 和 #8 从单个请求的角度测量处理 I/O 请求所需的时间,并将其乘以请求数量
  • 字段 #10 告诉您 I/O 路径中使用的实际经过时间(“挂钟”)

画一个近似平行结构:想象一下多核 CPU。两个进程可以同时占用 CPU,每个进程执行 60 秒。总 CPU 使用时间为 120 秒(60 秒 * 2),但实际运行的时钟时间仍然为 60 秒,因为两个进程同时运行。

相关内容