我注意到,当我查看/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)。我在想,如果有人能解释为什么这些数字是不同的,似乎第十个字段试图捕捉到与第四个和第八个字段之和不同的东西。
发布于 2017-07-15 20:58:08
我还没有看过源代码,但这一区别似乎源于两种不同的会计模式。
#4和#8字段之和每个请求完成所需的时间。这意味着,并行发出的请求仍然每个贡献,使计数增长。
#10字段只计算队列和磁盘繁忙的实际时间,因此它们将并行发出的请求计算为单个请求。
让我们做一个实际的例子。在/boot分区上,我dd a~4MB文件。看一下统计数据:
[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或~350 or。然而,计数器4和10的反应方式非常不同:第一次增加约4000次,而后者仅增加约350次。很容易看出哪一个值是“正确”的:它是字段#10,正如dd所知,整个操作花费了大约350 as,字段#10增加了同样的数量。
那么,为什么字段#4增加了这么多,它真正测量的是什么呢?
首先,让我们了解在请求级别上正在发生的事情。默认情况下,dd使用512 B请求,但是linux的粒度为4KB,因此我们应该期望得到大约1000x4KB请求。这1000个请求被放在一个队列中,一个接一个地发出(为了简单起见,让我们假装NCQ不存在)并被分派到磁盘。由于机械磁盘非常擅长顺序读取,所以它们通常使用预读策略--也就是说,它们读取的数据比所需的多。这意味着,在第一个4K请求完成后,所有其他后续请求都将在很短的时间内完成。
让我们来做一些数学,用疯狂的半化:
按字段#4: 1000个队列内请求*每个== 4000 4ms计算的总请求时间。这大概是4号字段增加的值.
要画出一种赞同的并行性:考虑多核CPU。两个进程可以同时锤击CPU,每个进程执行60次。使用的总CPU时间为120 s(60*2),但由于这两个进程同时运行,实际运行的时钟时间仍为60总时间。
https://serverfault.com/questions/862334
复制相似问题