iostat的util是如何计算的?

发布于 2024-10-08 01:27:50 字数 1527 浏览 9 评论 0原文

iostat -x -d 

可以显示很多I/O统计信息。 对于iostat的util,解释是:

向设备发出 I/O 请求期间的 CPU 时间百分比(设备的带宽利用率)。当该值接近 100% 时,设备就会饱和

我想知道 util 是如何计算的?

我做了一个实验,(见下面的代码),启动40个线程随机读取40个文件。我想磁盘利用率应该很高,但我错了, iostat如下,谁能给出为什么? THX

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

代码:

#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;
}
iostat -x -d 

can display many i/o statistic info.
For util of iostat, the explanation is :

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 want to know how the util was computed?

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

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;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

诗化ㄋ丶相逢 2024-10-15 01:27:50

%util 在 iostat 的源代码中被命名为 busy:https://code.google.com/p/tester-higkoo/source/browse/trunk/Tools/iostat/iostat.c#380

忙碌被统计以 Ticksdeltams 的百分比表示,限制为 100%

busy = 100.0 * blkio.ticks / deltams; /* percentage! */
if (busy > 100.0) busy = 100.0;

DeltaMS 是一段时间内系统负载的总和(用户时间 + 系统时间 + 空闲时间 + iowait)/中央处理器。

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 - 是一段时间内队列中请求的时间

blkio.ticks = new_blkio[p].ticks
                - old_blkio[p].ticks;

在 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 填入 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);

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 是从“sysfs stat for current block”读取的设备或分区” in read_sysfs_file_stat (iostat.c:487),ioiioj 是当前和之前的统计数据。

%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

Busy is counted as percent ratio of Ticks to deltams, limited to 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.

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

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

/*       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

/*
 * 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

  * @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.

攒一口袋星星 2024-10-15 01:27:50

iostat -x (我使用旧版本的源代码在实现之前写下它)显示来自 /proc/diskstats 的信息(记录在此处)和/proc/stat (有关 CPU 时间;请参阅 man proc(5 )) (还有其他一些,但这对于理解并不重要)。

您可以在 osgx 的答案中看到相关的代码片段,但我无法单独理解它们,因此这里有一个扩展解释:

  • %util = blkio.ticks / deltams * 100%
  • deltams 是自上次快照以来经过的时间(以毫秒为单位)。它使用来自 /proc/stat 的 CPU 统计信息,大概是因为它比依赖系统时间提供更好的结果,但我不确定。 (旁注:由于某种原因,时间除以 HZ,而 文档指出它位于USER_HZ中,我不明白。)
  • blkio.ticks 是“执行 I/O 所花费的毫秒数”,来自 /proc/ diskstats 文档

    字段 9 -- 当前正在进行的 I/O 数量
      唯一应该归零的字段。随着请求的增加而增加
      赋予适当的 struct request_queue 并在完成时递减。
    字段 10 -- 执行 I/O 所花费的毫秒数
      只要字段 9 非零,该字段就会增加。
    

    即我的理解是,ticks 是任何 I/O 请求(针对该设备)正在进行时的刻度数乘以刻度之间的持续时间。

所以 %util = 100% 意味着每次内核查看时(我猜在现代内核上是每秒 1000 次,请参阅“HZ”),I/O 请求正在进行中。

以下是关于 iostat 的另一篇文章的摘录:

[%util is] 存储设备有多少时间有未完成的工作(正忙)。

在正确的 RAID 环境中,它更像是“RAID 阵列中至少一个磁盘有多少时间有事可做”。我在这里故意排除任何类型的缓存 - 如果可以从缓存中提供请求,那么它出现在 %util 中的机会可以忽略不计,这与其他值不同。

这也意味着 – RAID 子系统可以从 6.25%(一个磁盘完成工作)加载到 100%(所有磁盘都忙)。对于“100%”的单一值来说,这是相当多的见解,不是吗?

iostat -x (I used an old version of the source code to 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).

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:

  • %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 by HZ, while the documentation states it's in USER_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.

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.

Here's an excerpt from another post on 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?

季末如歌 2024-10-15 01:27:50

根据手册页,iostat 的第一行结果是系统启动时的平均值。

从我的测试来看,这似乎也适用于唯一的行,如果称为“

iostat -x.

尝试”:

iostat -dmx 1 5

它将为您提供五行,行之间的差异为一秒。放弃第一个,看看其他的,也许这样的输出会更有意义。

As per the man page, the first line of results from iostat is an average from the moment the system was booted.

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.

失与倦" 2024-10-15 01:27:50

%util 表示每单位时间花费多少时间写入/读取,您可以根据平均服务时间计算它:

svctm  * (  r/s + w/s )  /1000 
= 0.66 *(0.24 + 0.57) /1000
= 0.0005346 

因此 0.05%

我还没有读过您的代码,但显然每秒读取或写入次数少于 1 次。不要加载那么多磁盘!

%util means how much time spent writing/reading per unit of time, you can compute it from the mean service time:

svctm  * (  r/s + w/s )  /1000 
= 0.66 *(0.24 + 0.57) /1000
= 0.0005346 

hence 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!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文