[转帖]磁盘负载指标 %iowait, await, %util 的正确理解

磁盘,负载,指标,iowait,await,util,正确理解 · 浏览次数 : 0

小编点评

归纳总结: 1.当 IO size 较小时, 硬盘即使压力不大( sdb 为 ssd ) %util 也达到了 30% , 后来当 IO size 为 1M 时磁盘实际负载并不会比之前低, 但是 %util 却很低, 这与要是由于不同 size 的 IO 造成内核 IO queue 里面停留时间不同造成的,和硬盘本身的负载并没有直接的关系。 2.当 IO size 为 1M 时, %util 却很低, 这与要是由于不同 size 的 IO 造成内核 IO queue 里面停留时间不同造成的,和硬盘本身的负载并没有直接的关系。 3.生成内容时需要带简单的排版,方便人们理解。

正文

说明

%iowait, await, %util 是用来衡量硬盘负载的三个指标, 但是这几个指标通常容易被误解, 实际上, 这三个指标单纯的高, 并不一定能说明相应的磁盘有问题或者有瓶颈, 而是需要结合具体执行 IO 操作的程序的执行方式, 综合的来判断指标高的原因.

关于 await, %util 的计算方式可以参照:
linux iostat 输出详解

总结

%iowait:

最容被误解的参数, 实际上这是一个非常宏观的系统指标, 其表示 "CPU空闲 并且 有未完成的IO " 这种状态在一个采样周期里的占比, 一般来说当一个进程进行同步的 IO 操作时, 进程将会被挂起, CPU 将会空闲, 等待 IO 完成, 这时候如果没有其它进程占用 CPU 此时的状态将会被计入 iowait 的统计时间以内. 但是 CPU 空闲也只是当前进程空闲, 空闲出来的 CPU 是可以进行其它操作的, 如果此时 %iowait 较高, 只能说明在等待 IO 完成的时间里系统没有其它进程来占用 CPU 了, 而 IO 未完成, 有可能只是单纯的 IO size 比较大, 完成需要较长时间, 并不一定是 IO 有问题.

而且如果等待 IO 完成时系统有其它繁忙的进程占用了 CPU, 那么无论此时 IO 完成时间多长(即使是IO完全卡死), %iowait 也会非常的低, 因为此时CPU不空闲了, 因为 %iowait 只是反映 "CPU空闲 并且 有未完成的IO " 这种状态时间的占比, 两个条件缺少一个都不会计入 iowait 的时间.

await

每个I/O的平均耗时, 包括在内核 IO 队列内的时间和在存储设备上执行此 IO 的时间, 所以 await 高可能有两个原因, 一是 IO 在 IO queue 里耗时较长, 另一个就是由于 IO 在存储设备上执行的时间比较长, 而 IO 在 IO queue 里耗时较长可能是由于程序一次并发了过多的 IO, 让 IO 在 queue 排队, IO 在存储设备上执行的时间比较长也有可能时 IO 本身就比较大, 例如在硬盘上写 1KB 文件, 耗时一定是比 1MB的时间短的, 所以 await 高, 还要结合业务本身的特点判断 await 高的原因

%util

这个反映 IO queue, 中存在 IO 在采样周期里的占比, 只要 IO queue 中存在 IO, 就会被计入到 %util 的时间内, 无论是 1 个 IO 或者 100 个IO, 并且也只计算 IO 存在于 queue 里面的时间, 所以此时即使磁盘压力较大, 但是 IO queue 中并没有排队的 IO 那么 %util 也不会高(例如每次 IO size 都比较大), 或者有些程序进行顺序 IO, 完成几个再发下一个, 并且 IO size 并不大, 此时即使磁盘压力较小 %util 也会比较高

测试

环境和命令

使用 fio 模拟客户端, 通过不同的 fio 引擎和不同的队列深度配置来模拟顺序的和并发的 IO

环境如下

[root@centos-76-c1~]# uname -a
Linux centos-76-c1 5.5.7-1.el7.elrepo.x86_64 #1 SMP Fri Feb 28 12:21:58 EST 2020 x86_64 x86_64 x86_64 GNU/Linux
[root@centos-76-c1~]# cat /etc/redhat-release 
CentOS Linux release 7.6.1810 (Core) 
[root@centos-76-c1~]# fio --version
fio-3.1

    使用 iostat -mx 1 10000 sdb 来模监控 %iowait, await , %util 具体数值

    [root@centos-76-c1~]# iostat -mx 1 10000 sdb
    Linux 5.5.7-1.el7.elrepo.x86_64 (centos-76-c1) 	03/05/2020 	_x86_64_	(1 CPU)
    

    avg-cpu: %user %nice %system %iowait %steal %idle
    1.46 0.00 0.78 12.33 0.00 85.43

    Device: rrqm/s wrqm/s r/s w/s rMB/s wMB/s avgrq-sz avgqu-sz await r_await w_await svctm %util
    sdb 0.00 0.66 0.60 263.41 0.01 1.17 9.20 21.27 81.06 7.02 81.23 0.16 4.23

    avg-cpu: %user %nice %system %iowait %steal %idle
    0.00 0.00 0.00 0.00 0.00 100.00

    Device: rrqm/s wrqm/s r/s w/s rMB/s wMB/s avgrq-sz avgqu-sz await r_await w_await svctm %util
    sdb 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00

    ......

      %iowait

      %iowait 与 CPU 本身的关系

      找一个 CPU 空闲的时期

      [root@centos-76-c1~]# top -n 1
      top - 17:38:33 up  1:02,  3 users,  load average: 0.00, 0.10, 0.12
      Tasks: 136 total,   1 running,  81 sleeping,   0 stopped,   0 zombie
      %Cpu(s):  0.0 us,  0.0 sy,  0.0 ni,100.0 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
      KiB Mem :   977804 total,   696812 free,   105696 used,   175296 buff/cache
      KiB Swap:  1572860 total,  1572860 free,        0 used.   697424 avail Mem 
      

        随便增加一些负载差不多的普通负载, 观察此时的 iowait

        [root@centos-76-c1~]# fio --name=randwrite --rw=randwrite --bs=16k --size=1G --runtime=60 --ramp_time=20 --ioengine=sync --numjobs=1 --filename=/dev/sdb --direct=1 --group_reporting 
        randwrite: (g=0): rw=randwrite, bs=(R) 16.0KiB-16.0KiB, (W) 16.0KiB-16.0KiB, (T) 16.0KiB-16.0KiB, ioengine=sync, iodepth=1
        fio-3.1
        Starting 1 process
        Jobs: 1 (f=1): [w(1)][100.0%][r=0KiB/s,w=1472KiB/s][r=0,w=92 IOPS][eta 00m:00s]
        randwrite: (groupid=0, jobs=1): err= 0: pid=7724: Thu Mar  5 17:56:42 2020
          write: IOPS=86, BW=1390KiB/s (1423kB/s)(81.5MiB/60004msec)
            clat (usec): min=2917, max=48358, avg=11505.79, stdev=4808.19
             lat (usec): min=2918, max=48359, avg=11506.34, stdev=4808.19
        .....
        

          iowait 达到了 99%

          ......
          avg-cpu:  %user   %nice %system %iowait  %steal   %idle
                     0.00    0.00    1.00   99.00    0.00    0.00
          

          Device: rrqm/s wrqm/s r/s w/s rMB/s wMB/s avgrq-sz avgqu-sz await r_await w_await svctm %util
          sdb 0.00 0.00 0.00 101.00 0.00 1.58 32.00 0.94 9.86 0.00 9.86 1.02 10.30

          avg-cpu: %user %nice %system %iowait %steal %idle
          0.00 0.00 0.00 100.00 0.00 0.00

          Device: rrqm/s wrqm/s r/s w/s rMB/s wMB/s avgrq-sz avgqu-sz await r_await w_await svctm %util
          sdb 0.00 0.00 0.00 97.96 0.00 1.53 32.00 0.97 10.41 0.00 10.41 1.02 10.00
          ......

            此时增加一个十分耗费 CPU 的计算圆周率的命令, 计算 50000 位的圆周率

            [root@centos-76-c1~]# time echo "scale=50000; 8*a(1)" | bc -l -q
            
            • 1

            此时 CPU 利用率已经非常高

            [root@centos-76-c1~]# top -n 1
            top - 17:59:21 up  1:22,  3 users,  load average: 0.21, 0.17, 0.09
            Tasks: 138 total,   2 running,  81 sleeping,   0 stopped,   0 zombie
            %Cpu(s):100.0 us,  0.0 sy,  0.0 ni,  0.0 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
            KiB Mem :   977804 total,   696652 free,   105816 used,   175336 buff/cache
            KiB Swap:  1572860 total,  1572860 free,        0 used.   697288 avail Mem
            

              这是可以看到 %iowait 直接变成了 0.00

              ......
              avg-cpu:  %user   %nice %system %iowait  %steal   %idle
                       100.00    0.00    0.00    0.00    0.00    0.00
              

              Device: rrqm/s wrqm/s r/s w/s rMB/s wMB/s avgrq-sz avgqu-sz await r_await w_await svctm %util
              sdb 0.00 0.00 0.00 66.00 0.00 1.03 32.00 0.66 10.48 0.00 10.48 1.98 13.10

              avg-cpu: %user %nice %system %iowait %steal %idle
              99.01 0.00 0.99 0.00 0.00 0.00

              Device: rrqm/s wrqm/s r/s w/s rMB/s wMB/s avgrq-sz avgqu-sz await r_await w_await svctm %util
              sdb 0.00 0.00 0.00 69.31 0.00 1.08 32.00 0.66 10.11 0.00 10.11 2.00 13.86
              ......

                总结

                通过上面的测试可以证明 %iowait 是一个十分宏观的一个参数, 系统其他服务对 CPU 的利用会直接影响这个数值, 如果 CPU 利用率够高, 即使此时 IO 完全卡死, 此时 %iowait 可能也很低. %iowait 即使很高, 实际上硬盘的压力可能也不大.

                await

                await 和 iodepth 的关系

                使用 fio 模拟客户端, 固定大小的 io 请求, 通过配置不同的 --iodepth= --iodepth_batch_submit= --iodepth_low= 来实现不同并发度的 IO

                [root@centos-76-c1~]# fio --name=randwrite --rw=randwrite --bs=4k --size=1G --runtime=60 --ramp_time=20 --ioengine=libaio --iodepth=<iodepth> --iodepth_batch_submit=<iodepth> --iodepth_low=<iodepth>  --numjobs=1 --filename=/dev/sdb --direct=1 --group_reporting
                
                  测试结果
                  iodepthIOPSBWavgqu-szawait
                  190363KiB/s0.203.03
                  43371349KiB/s2.176.51
                  1611684676KiB/s10.007.50
                  6418287317KiB/s47.9718.33
                  25618517424KiB/s252.03300 ~ 500
                  102417236963KiB/s270.84300 ~ 600
                  总结

                  随着并发度越来越高, 达到了本机 IO 能承受的 IO 的上限, 大量 IO 在存储集群里面排队, 可以看到 await 随着 IO 在队列中排队时间的增大而逐渐增大

                  await 和 iosize 的关系

                  使用 fio 模拟客户端, 固定大小的 io iodept, 通过配置不同的 --bs=<block_size> 来实现不同<block_size>的 IO (block_size 即一次读写的文件的大小)

                  [root@centos-76-c1~]# fio --name=randwrite --rw=randwrite --bs=<block_size>  --size=1G --runtime=60 --ramp_time=20 --ioengine=libaio --iodepth=1 --iodepth_batch_submit=1 --iodepth_low=1  --numjobs=1 --filename=/dev/sdb --direct=1 --group_reporting
                  
                  • 1
                  测试结果
                  block_sizeIOPSBWavgrq-szavgqu-szawait
                  4KiB90364KiB/s8.000.252.93
                  16KiB691120KiB/s32.000.649.75
                  64KiB301948KiB/s128.000.8430.11
                  256KiB113004KiB/s512.000.9389.90
                  1MiB44168KiB/s2048.001.14227.00
                  4MiB14531KiB/s2048.00 - 2560.003.46902.75
                  16MiB05206KiB/s2048.00 - 2560.0012.502223.40
                  总结

                  可以看到随着 block_size 即 一次读写的文件的大小不断增加, await 也逐渐增加, 实际上此时 IO 并不能说 IO 是瓶颈, 或者 IO 延时过高, 只是单纯的完成大 IO 耗时更长

                  %util

                  %util 与 IO 的关系

                  使用 fio 分别测试不同 iosize 的同步 IO

                  [root@centos-76-c1~]# fio --name=randwrite --rw=randwrite --bs=4K --size=1G --runtime=60 --ramp_time=20 --ioengine=sync --numjobs=4 --filename=/dev/sdb --direct=1 --group_reporting --sync=1
                  randrw: (g=0): rw=randwrite, bs=(R) 4096B-4096B, (W) 4096B-4096B, (T) 4096B-4096B, ioengine=sync, iodepth=1
                  
                    ...
                    fio-3.1
                    Starting 4 processes
                    Jobs: 2 (f=2): [E(0),w(4)][100.0%][r=0KiB/s,w=1081KiB/s][r=0,w=270 IOPS][eta 00m:00s]
                    randrw: (groupid=0, jobs=4): err= 0: pid=8310: Thu Mar  5 19:24:57 2020
                      write: IOPS=292, BW=1169KiB/s (1197kB/s)(68.5MiB/60004msec)
                    

                    ......

                      ......
                      Davg-cpu:  %user   %nice %system %iowait  %steal   %idle
                               100.00    0.00    0.00    0.00    0.00    0.00
                      

                      Device: rrqm/s wrqm/s r/s w/s rMB/s wMB/s avgrq-sz avgqu-sz await r_await w_await svctm %util
                      sdb 0.00 0.00 0.00 325.00 0.00 1.27 8.00 2.17 7.18 0.00 7.18 1.17 38.10

                      avg-cpu: %user %nice %system %iowait %steal %idle
                      99.00 0.00 1.00 0.00 0.00 0.00

                      Device: rrqm/s wrqm/s r/s w/s rMB/s wMB/s avgrq-sz avgqu-sz await r_await w_await svctm %util
                      sdb 0.00 0.00 0.00 309.00 0.00 1.21 8.00 2.28 7.87 0.00 7.87 1.08 33.40
                      ......

                        [root@centos-76-c1~]# fio --name=randwrite --rw=randwrite --bs=1m --size=1G --runtime=60 --ramp_time=20 --ioengine=sync --numjobs=4 --filename=/dev/sdb --direct=1 --group_reporting --sync=1
                        randwrite: (g=0): rw=randwrite, bs=(R) 1024KiB-1024KiB, (W) 1024KiB-1024KiB, (T) 1024KiB-1024KiB, ioengine=sync, iodepth=1
                        ...
                        
                          fio-3.1
                          Starting 4 processes
                          Jobs: 3 (f=3): [w(3),_(1)][58.2%][r=0KiB/s,w=4096KiB/s][r=0,w=4 IOPS][eta 00m:59s]
                          randwrite: (groupid=0, jobs=4): err= 0: pid=8396: Thu Mar  5 19:32:23 2020
                            write: IOPS=4, BW=4407KiB/s (4513kB/s)(261MiB/60647msec)
                              clat (msec): min=406, max=1552, avg=928.17, stdev=188.99
                               lat (msec): min=406, max=1552, avg=928.21, stdev=188.99
                          ......
                          
                            ......
                            

                            Device: rrqm/s wrqm/s r/s w/s rMB/s wMB/s avgrq-sz avgqu-sz await r_await w_await svctm %util
                            sdb 0.00 0.00 0.00 5.00 0.00 5.00 2048.00 3.77 753.40 0.00 753.40 2.00 1.00

                            avg-cpu: %user %nice %system %iowait %steal %idle
                            99.01 0.00 0.99 0.00 0.00 0.00

                            Device: rrqm/s wrqm/s r/s w/s rMB/s wMB/s avgrq-sz avgqu-sz await r_await w_await svctm %util
                            sdb 0.00 0.00 0.00 3.96 0.00 3.96 2048.00 3.40 860.50 0.00 860.50 2.00 0.79

                              总结

                              可以看到当 IO size 较小时, 硬盘即使压力不大( sdb 为 ssd ) %util 也达到了 30% , 后来当 IO size 为 1M 时磁盘实际负载并不会比之前低, 但是 %util 却很低, 这与要是由于不同 size 的 IO 造成内核 IO queue 里面停留时间不同造成的, 和硬盘本身的负载并没有直接的关系

                              与[转帖]磁盘负载指标 %iowait, await, %util 的正确理解相似的内容:

                              [转帖]磁盘负载指标 %iowait, await, %util 的正确理解

                              说明 %iowait, await, %util 是用来衡量硬盘负载的三个指标, 但是这几个指标通常容易被误解, 实际上, 这三个指标单纯的高, 并不一定能说明相应的磁盘有问题或者有瓶颈, 而是需要结合具体执行 IO 操作的程序的执行方式, 综合的来判断指标高的原因. 关于 await, %util

                              [转帖]磁盘负载指标 %iowait, await, %util 的正确理解

                              说明 %iowait, await, %util 是用来衡量硬盘负载的三个指标, 但是这几个指标通常容易被误解, 实际上, 这三个指标单纯的高, 并不一定能说明相应的磁盘有问题或者有瓶颈, 而是需要结合具体执行 IO 操作的程序的执行方式, 综合的来判断指标高的原因. 关于 await, %util

                              【转帖】FIO磁盘性能测试工具

                              https://www.jianshu.com/p/70b8c7d5d217 FIO工具介绍 FIO 工具是一款用于测试硬件存储性能的辅助工具,兼具灵活性、可靠性从而从众多性能测试工具中脱颖而出。磁盘的 I/O 是衡量硬件性能的最重要的指标之一,而 FIO 工具通过模拟 I/O负载对存储介质进行压力

                              [转帖]文件系统读写性能fio测试方法及参数详解

                              简介 Fio 是一个 I/O 工具,用来对硬件进行压力测试和验证,磁盘IO是检查磁盘性能的重要指标,可以按照负载情况分成照顺序读写,随机读写两大类。 Fio支持13种不同的I/O引擎,包括:sync, mmap, libaio, posixaio, SG v3, splice, null, netw

                              [转帖]FIO使用说明

                              FIO介绍: FIO是测试IOPS的非常好的工具,用来对磁盘进行压力测试和验证。磁盘IO是检查磁盘性能的重要指标,可以按照负载情况分成照顺序读写,随机读写两大类。FIO是一个可以产生很多线程或进程并执行用户指定的特定类型I/O操作的工具,FIO的典型用途是编写和模拟的I/O负载匹配的作业文件。也就是

                              [转帖]Linux性能分析:理解系统平均负载

                              Linux系统中,平均负载是指单位时间内,处于可运行状态和不可中断状态的进程数。它不仅包括了正在使用CPU的进程,也包括处于不可打断的睡眠状态的进程—它们是在等待其它系统资源如磁盘 I/O 等的进程。而CPU使用率,是单位时间内CPU繁忙情况的统计,跟平均负载并不一定完全对应。 有诸多方式监测系统平

                              [转帖]对磁盘进行基准检验

                              对磁盘进行基准检验https://learn.microsoft.com/zh-cn/azure/virtual-machines/disks-benchmarks 适用于:✔️ Linux VM ✔️ Windows VM ✔️ 灵活规模集 ✔️ 统一规模集 基准测试是指模拟应用程序的不同工作负荷

                              [转帖]Centos 7 查看磁盘io ,找出占用io读写很高的进程

                              1,先用iostat查看磁盘io 是否读写负载很高 用iostat -x 1 10 如果 iostat 没有,要 yum install sysstat安装这个包,第一眼看下图红色圈圈的那个如果%util接近100%,表明I/O请求太多,I/O系统已经满负荷,磁盘可能存在瓶颈,一般%util大于70

                              [转帖]在Linux上施加高CPU负载和压力测试,牛皮!

                              https://cloud.tencent.com/developer/article/2048995 在日常工作中,CPU压力测试是一项常见的工作,主要用到如下场景: 微调系统上的活动。 监控操作系统内核接口。 测试您的Linux硬件组件,例如CPU、内存、磁盘设备和许多其他组件,以观察它们在压力

                              [转帖]Linux使用Stress-ng测试CPU、内存、磁盘I/O满载情况教程与范例

                              https://www.xiaoyuanjiu.com/108301.html 介绍如何在 Linux 系统上使用 stress-ng 负载测试工具,产生 CPU、内存等资源满载的状况。 stress-ng stress-ng 与旧的 stress 都可以用来产生系统负载,但新的 stress-ng