Linux iostat 的 util 是如何计算的?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4458183/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How the util of iostat is computed?
提问by Raymond
iostat -x -d
can display many i/o statistic info. For util of iostat, the explanation is :
可以显示很多 i/o 统计信息。对于iostat的util,解释如下:
Percentage of CPU time during which I/O requests were issued to the device (band-width utilization for the device). Device saturation occurs when this value is close to 100%
向设备发出 I/O 请求的 CPU 时间百分比(设备的带宽利用率)。当该值接近 100% 时会发生设备饱和
I want to know how the util was computed?
我想知道util是如何计算的?
I make an experiment, (see following code), start 40 thread to randomly read 40 files. I suppose the disk util should be very high, but I am wrong, the iostat is as follow, anyone can give why? THX
我做了一个实验,(见下面代码),启动40个线程随机读取40个文件。我想磁盘 util 应该很高,但我错了,iostat 如下,任何人都可以给出为什么?谢谢
Device: rrqm/s wrqm/s r/s w/s rsec/s wsec/s avgrq-sz avgqu-sz await svctm %util
sdb1 0.01 0.44 0.24 0.57 3.44 8.14 14.34 0.00 2.28 0.66 0.05
Code:
代码:
#include <iostream>
#include <fstream>
#include <pthread.h>
using namespace std;
void* work(void* a)
{
int* id = (int*)a;
string file = "sys.partition";
char buf[100];
sprintf(buf, "%d", *id);
file.append(string(buf));
ifstream in(file.c_str());
in.seekg(0, ios_base::end);
size_t len = in.tellg();
cout << "open file : " << file << " , " << len << endl;
srand(time(NULL));
while(true)
{
size_t pos = rand() % len;
in.seekg(pos);
//cout << pos << endl;
in.read(buf, 10);
system("sync");
}
in.close();
}
int main(int argc, char** argv)
{
static const int num = 40;
pthread_t threads[num];
for (int i = 0; i < num; i++) {
pthread_create(&threads[i], NULL, work, &i);
}
for (int i = 0; i < num; i++) {
pthread_join(threads[i], NULL);
}
return 0;
}
采纳答案by osgx
%util
is named busy in the source code of iostat: https://code.google.com/p/tester-higkoo/source/browse/trunk/Tools/iostat/iostat.c#380
%util
在iostat的源码中被命名为busy:https: //code.google.com/p/tester-higkoo/source/browse/trunk/Tools/iostat/iostat.c#380
Busy is counted as percent ratio of Ticks
to deltams
, limited to 100%
Busy 计算为Ticks
to 的百分比deltams
,限制为 100%
busy = 100.0 * blkio.ticks / deltams; /* percentage! */
if (busy > 100.0) busy = 100.0;
DeltaMS is sum of system load for the period of time (user time + system time + idle time + iowait)/ ncpu.
DeltaMS 是一段时间内系统负载的总和(用户时间+系统时间+空闲时间+iowait)/ncpu。
double deltams = 1000.0 *
((new_cpu.user + new_cpu.system +
new_cpu.idle + new_cpu.iowait) -
(old_cpu.user + old_cpu.system +
old_cpu.idle + old_cpu.iowait)) / ncpu / HZ;
Ticks - is the Time of requests in queue
for the period
Ticks - 是Time of requests in queue
期间
blkio.ticks = new_blkio[p].ticks
- old_blkio[p].ticks;
In more current version of sysstat the code is bit different: http://sources.debian.net/src/sysstat/10.2.0-1/iostat.c#L959
在较新版本的 sysstat 中,代码有点不同:http: //sources.debian.net/src/sysstat/10.2.0-1/iostat.c#L959
/* rrq/s wrq/s r/s w/s rsec wsec rqsz qusz await r_await w_await svctm %util */
printf(" %8.2f %8.2f %7.2f %7.2f %8.2f %8.2f %8.2f %8.2f %7.2f %7.2f %7.2f %6.2f %6.2f\n",
...
/*
* Again: Ticks in milliseconds.
* In the case of a device group (option -g), shi->used is the number of
* devices in the group. Else shi->used equals 1.
*/
shi->used ? xds.util / 10.0 / (double) shi->used
: xds.util / 10.0); /* shi->used should never be null here */
xds is filled in the compute_ext_disk_stats(&sdc, &sdp, itv, &xds);
http://sources.debian.net/src/sysstat/10.2.0-1/common.c?hl=679#L679
xds 填写在compute_ext_disk_stats(&sdc, &sdp, itv, &xds);
http://sources.debian.net/src/sysstat/10.2.0-1/common.c?hl=679#L679
/*
* Macros used to display statistics values.
*
* HZ is 1024 on IA64 and % should be normalized to 100.
*/
#define S_VALUE(m,n,p) (((double) ((n) - (m))) / (p) * HZ)
xds->util = S_VALUE(sdp->tot_ticks, sdc->tot_ticks, itv);
And there is the filling of tot_ticks from iostat.c
还有来自iostat.c的tot_ticks的填充
* @ioi Current sample statistics.
* @ioj Previous sample statistics.
* @itv Interval of time.
...
sdc.tot_ticks = ioi->tot_ticks;
sdp.tot_ticks = ioj->tot_ticks;
tot_ticks
are read from "sysfs stat for current block device or partition" in read_sysfs_file_stat
(iostat.c:487), and ioi
and ioj
are current and previous stat.
tot_ticks
从( iostat.c:487) 中的“当前块设备或分区的 sysfs 统计信息”中读取,并且是当前和以前的统计信息。read_sysfs_file_stat
ioi
ioj
回答by Nickolay
iostat -x
(I used an old version of the source codeto write this up before realizing it) displays information from /proc/diskstats
(documented here) and /proc/stat
(for CPU times; see man proc(5)) (and a few others, but that's not important for understanding).
iostat -x
(我在实现之前使用了旧版本的源代码来编写它)显示来自/proc/diskstats
(此处记录)和/proc/stat
(对于 CPU 时间;请参阅man proc(5))(以及其他一些信息,但这对于理解并不重要)。
You can see the relevant snippets of code in osgx's answer, but I couldn't make sense of them in isolation, so here's an extended explanation:
您可以在 osgx 的答案中看到相关的代码片段,但我无法孤立地理解它们,所以这里有一个扩展的解释:
%util = blkio.ticks / deltams * 100%
deltams
is the time elapsed since last snapshot in ms. It uses CPU stats from/proc/stat
presumably because it gives better results than to rely on system time, but I don't know for sure. (Side note: for some reason the times are divided byHZ
, while the documentationstates it's inUSER_HZ
, I don't understand that.)blkio.ticks
is "# of milliseconds spent doing I/Os", from/proc/diskstats
docs:Field 9 -- # of I/Os currently in progress The only field that should go to zero. Incremented as requests are given to appropriate struct request_queue and decremented as they finish. Field 10 -- # of milliseconds spent doing I/Os This field increases so long as field 9 is nonzero.
i.e. my understanding is that
ticks
is the number of ticks when any I/O request (for this device) was in progress multiplied by the duration between ticks.
%util = blkio.ticks / deltams * 100%
deltams
是自上次快照以来经过的时间(以毫秒为单位)。它使用 CPU 统计数据,/proc/stat
大概是因为它比依赖系统时间提供更好的结果,但我不确定。(旁注:由于某种原因,时间被 划分HZ
,而文档说明它在 中USER_HZ
,我不明白。)blkio.ticks
是“花费在 I/O 上的毫秒数”,来自/proc/diskstats
文档:Field 9 -- # of I/Os currently in progress The only field that should go to zero. Incremented as requests are given to appropriate struct request_queue and decremented as they finish. Field 10 -- # of milliseconds spent doing I/Os This field increases so long as field 9 is nonzero.
即我的理解是
ticks
任何 I/O 请求(针对此设备)正在进行时的滴答数乘以滴答之间的持续时间。
So %util = 100%
means that each time the kernel looked (I guess it's 1000 times per second on modern kernels, see "HZ"), an I/O request was in progress.
这%util = 100%
意味着每次内核查看时(我猜在现代内核上是每秒 1000 次,参见“HZ”),一个 I/O 请求正在进行中。
Here's an excerpt from another post on iostat:
这是iostat 上另一篇文章的摘录:
[%util is] how much time did the storage device have outstanding work (was busy).
In proper RAID environments it is more like “how much time did at least one disk in RAID array have something to do”. I'm deliberately excluding any kind of cache here – if request can be served from cache, the chance is quite negligible it will show up in %util, unlike in other values.
What this also means – the RAID subsystem can be loaded from 6.25% (one disk doing the work) to 100% (all of them busy). Thats quite a lot of insight in single value of '100%', isn't it?
[%util is] 存储设备有多少时间有未完成的工作(忙碌)。
在适当的 RAID 环境中,它更像是“RAID 阵列中至少一个磁盘有多少时间可以做某事”。我在这里特意排除了任何类型的缓存——如果请求可以从缓存中提供,那么它出现在 %util 中的机会就可以忽略不计,这与其他值不同。
这也意味着 - RAID 子系统可以从 6.25%(一个磁盘完成工作)加载到 100%(所有磁盘都忙)。这对“100%”的单一值有很多见解,不是吗?
回答by Wences
As per the man page, the first line of results from iostat is an average from the moment the system was booted.
根据手册页,iostat 的第一行结果是系统启动时的平均值。
From my tests, this seems to apply also to the only line, if called e.g. as
从我的测试来看,这似乎也适用于唯一的行,如果被称为例如
iostat -x.
Try:
尝试:
iostat -dmx 1 5
It will give you five lines with one second difference between lines. Discard the first, look at the others, perhaps like that the output will make more sense.
它将为您提供五行,行与行之间的差异为一秒。丢弃第一个,看看其他的,也许这样输出会更有意义。
回答by phil_w
%util means how much time spent writing/reading per unit of time, you can compute it from the mean service time:
%util 表示每单位时间写/读花费多少时间,可以从平均服务时间计算:
svctm * ( r/s + w/s ) /1000
= 0.66 *(0.24 + 0.57) /1000
= 0.0005346
hence 0.05%
因此 0.05%
I haven't read your code, but obviously at less than 1 read or write per second it isn't loading the disks that much!
我没有读过你的代码,但显然每秒读取或写入少于 1 次,它并没有加载那么多磁盘!