【问题标题】:How the util of iostat is computed?iostat 的 util 是如何计算的?
【发布时间】:2019-11-25 21:48:47
【问题描述】:
iostat -x -d 

可以显示许多 i/o 统计信息。 对于iostat的util,解释为:

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

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

我做了一个实验,(见下面的代码),启动40个线程随机读取40个文件。我想磁盘利用率应该很高,但我错了, 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

代码:

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

【问题讨论】:

  • 格式完全改变,溢出应该改进编辑器。
  • 溢出来救援!改进完成!
  • 要么查看@zengr 对您的问题所做的更改,要么阅读格式帮助:stackoverflow.com/editing-help

标签: linux linux-kernel linux-device-driver


【解决方案1】:

%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)/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 - 是期间的Time of requests in queue

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(&amp;sdc, &amp;sdp, itv, &amp;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 是从 read_sysfs_file_stat (iostat.c:487) 中的“sysfs stat for current block device or partition”中读取的,ioiioj 是当前和以前的统计信息。

【讨论】:

  • 非常感谢,但我不知道如何接受您的回答?
  • @Raymond,你明白了吗,“队列中的请求时间”是什么意思?我无法完全理解这个参数,但我认为它类似于发出和完成磁盘请求之间的平均时间
  • 但是...... OP 问题的答案是什么I suppose the disk util should be very high, but I am wrong, the iostat is low, anyone can explain why?
  • 这叫做缓存:OS缓存了从磁盘读取的文件数据在页面缓存中:en.wikipedia.org/wiki/Page_cache - iostat报告的实际磁盘利用率很低,低于1%,所以作者的测试不正确,它没有测量任何磁盘延迟/速度,只测量操作系统如何管理来自内存的随机请求。
【解决方案2】:

iostat -x(我在意识到之前用an old version of the source code 写了这个)显示来自/proc/diskstats(记录在here)和/proc/stat(CPU 时间;参见man proc(5))(以及一些其他的,但这对于理解并不重要)。

你可以在osgx的回答中看到相关的sn-ps代码,但是我无法孤立地理解它们,所以这里有一个扩展的解释:

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

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

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

这是another post on iostat的摘录:

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

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

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

【讨论】:

  • 如果在所有 iostat 样本上看到平均队列大小 (avgqu-sz) 大于 1(假设 1 秒样本超过 100 秒),这是否意味着利用率将为 100%那100秒?因为队列很大意味着设备有足够的 I/O 来处理。
  • 我认为这是不对的,如果您正在考虑 1 秒 averages - 人们声称 await = avgqu-sz * svctm / (%util/100)。另一方面,如果队列 总是 非空(而不是简单地平均 1/秒),我希望 %util 为 100。
【解决方案3】:

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

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

iostat -x.

试试:

iostat -dmx 1 5

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

【讨论】:

    【解决方案4】:

    %util 表示每单位时间写入/读取所花费的时间,可以从平均服务时间计算:

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

    因此为 0.05%

    我还没有阅读您的代码,但显然每秒读取或写入不到 1 次,它不会加载那么多磁盘!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-07-07
      • 2011-10-16
      • 2019-02-03
      • 2018-11-03
      • 1970-01-01
      • 2010-11-27
      • 2013-08-17
      • 2010-09-14
      相关资源
      最近更新 更多