本文将讨论 iowait 的含义、相关的统计数据、原理以及 iowait的瓶颈问题 什么是 iowait Linux 中的解释 Show the percentage of time that the 的百分比值都是针对所有的 CPU 来说的,统计的是全局的信息,并不是指单个进程的数据 根据 iowait的定义可知, iowait是属于 idle的一个子类,为了便于理解,可以把 iowait 当成一种等待 计数为 0 , idle 计数为 95,则 它们的百分比依次为:2%、 %3、 0%、 95% iowait 常见的误解 有些同学可能对 iowait 的理解有偏差,常见的误解大概有以下几点 iowait 表示等待IO完成,在此期间 CPU 不能接受其他任务 从上面 iowait 的定义可以知道,iowait 表示 CPU 处于空闲状态并且有未完成的磁盘 IO 请求,也就是说,iowait 的首要条件就是 ,仅根据 %iowait 的上升是不能确定 IO 负载增加的结论 如何确定磁盘IO的瓶颈 通过前面的讲述,可以发现 %iowait 包含的信息量还不足以判断出 磁盘IO 是否存在瓶颈 当 %iowait
IOWait高的一些处理方法 1、检查RAID的状态,比如是否正在重建或者没有初始化 2、替换操作系统的内核,最好使用发行版标准的Linux kernel,因为有比较多的补丁 3、检查/proc/sys xfs文件系统时, 可以调节一些参数优化性能 5、客户端程序是否产生了过大的压力,比如磁盘的读写性能只有10MB/s,每个线程的读写 速度为5MB/s,那么如果读写线程数为20的话,无疑会造成IOWait
我们经常遇到iowait这个名词,在top命令中,vmstat中,sar命令中,都有它的身影。很多同学按照经验,当看到iowait非常高的时候,一般判定为磁盘I/O有瓶颈,但这并不完全正确。 iowait处于100%时,还能够运行其他CPU密集型应用么? iowait处于90%以上,就一定证明io有问题么? iowait占用非常少时,就一定证明io没问题么? 1. 数值来自哪? 在info命令中,可以看到iowait的解释。 此时,iowait就是66%,而user就是33%。 而如果换成了ssd,写磁盘只花费了1ms。那么此时的tps = 90,iowait就变成了 8%左右。 100%的iowait没有问题,但1%的iowait问题却很大。
Iowait是如何计算的? 先说说用户如何看到iowait吧 我们通常用vmstat就能看到iowat,图中的wa就是(标红) ? ()); … 这部分代码会输出你在/proc/stat中看到的数据,通过代码我们得知iowait来自 iowait = cputime64_add(iowait, kstat_cpu(i).cpustat.iowait ) > 0)//既不做中断,而且在idle,那么就是iowait cpustat->iowait = cputime64_add(cpustat->iowait, tmp); else cpustat 谁在产生iowait? 那么是谁修改了rq->nr_iowait呢? 重点终于来了,呵呵。 可以看到,iowait水平又降低了不少,那么此时此刻,谁还在制造iowait呢?
一堆 app 僵尸进程 iowait 分析 一提到 iowait 升高,首先会想要查询系统的 I/O 情况 运行 dstat 命令,观察 CPU 和 I/O 的使用情况 dstat 1 10 ? 当 iowait 升高(wai)时,磁盘的读请求(read)都会很大(M) 这说明 iowait 的升高跟磁盘的读请求有关,很可能就是读磁盘导致的 找到读磁盘的进程 通过 top 找到 D 状态的两个 僵尸进程(Z 状态)没有了, iowait 也是 0,问题终于全部解决了 总结 这个案例是因为磁盘 I/O 导致了 iowait 升高 不过,iowait 高并不一定代表 I/O 有性能瓶颈 当系统中只有 I/O 类型的进程在运行时,iowait 也会很高,但实际上,磁盘的读写远没有达到性能瓶颈的程度 分析整体思路 通过 top 查看系统资源情况 发现平均负载逐渐升高,iowait(wa)比较高,但用户态和内核态 的上升导系统平均负载上升 因为是 iowait 较高,可以通过 dstat 查看系统的 I/O 情况,会发现每次 iowait 升高,读磁盘请求都会很大 通过 pidstat -d 查看 D 状态进程的
当task发生iowait的时候,内核对他们的处理方法是将task切换出去,让可运行的task先运行,而在切换出去前,会将其in_iowait设置为1,再次被唤醒的时候in_iowait被设置为原值。 例如: 由此可见in_iowait表明了这个task是否在iowait。 在进程切换函数__schedule在切换task的时候,如果被切换出的task的in_iowait为真,则会对这个CPU的运行队列rq结构中的nr_iowait加1。 由此可见nr_iowait可以表明某CPU上是否有task在iowait,以及数量。 当累加系统idle时间的时候,如果CPU的nr_iowait为真,也就是当前这个cpu有task在等待iowait,则记录为iowait时间。
IOWait完全消失了,现在这个系统看起来完全没有受到I/O限制! 实际上,我们的第一个工作负载没有改变——它仍然受到I/O限制;只是当我们查看“IOWait”时,它变得看不见了! 要理解发生了什么,我们真的需要理解“IOWait”是什么以及它是如何计算的。 有一篇很好的文章对这个主题进行了更详细的介绍,但基本上,“IOWait”是闲置的CPU时间。 然而,如果CPU核因为某个进程正在等待磁盘而处于空闲状态,则I/O时间被归类到“IOWait”中。 因此,高IOWait显示系统中许多进程在等待磁盘I/O,但即使IOWait很低,磁盘I/O在系统上的某些进程中可能仍会有瓶颈。 /understanding-linux-iowait/
但是基于top中的wa和mpstat中的%iowait的多年判断经验。我当时说是在等io的。 当时我还说,如果我判断错了,下次见面,我请他喝花酒(不是你想的花酒, ? )。 虽然看到的是pidstat输出的CPU的wait,但是却和mpstat的iowait以及top中的wa对应不上。 ? 从上图可以看出,mpstat输出的%iowait并没有值,但是pidstat中的%wait却有比较高的值。在同一时间输出的数据相差如此之大,确实有蹊跷。 于是,我问他的环境中的版本是什么。 wa, IO-wait : time waiting for I/O completion mpstat中的iowait是这样的。 %iowait Show the percentage of time that the CPU or CPUs were idle during which the system had an
0.03%, steal 0.15%) server cpu = total 8.09% (user 2.73%, nice 0.05%, system 5.18%, iowait 0.00% 0.07%, steal 0.10%) server cpu = total 10.78% (user 1.76%, nice 0.02%, system 8.98%, iowait 0.02% 0.07%, steal 0.00%) server cpu = total 2.45% (user 1.14%, nice 0.09%, system 1.22%, iowait 0.00% 0.09%, steal 0.07%) server cpu = total 7.61% (user 1.49%, nice 0.07%, system 5.98%, iowait 0.02% 0.09%, steal 0.00%) server cpu = total 8.14% (user 1.59%, nice 0.02%, system 6.48%, iowait 0.00%
(该系统只有一个CPU core),发现该CPU的%usr长期维持在70%左右,且%sys也长期维持在20%左右: 03:56:29 AM CPU %usr %nice %sys %iowait < scp->cpu_iowait) && (scp->cpu_iowait < (ULLONG_MAX - 0x7ffff))) { /* * The iowait value reported by the kernel can also decrement as * a result of inaccurate iowait tracking. Waiting on IO can be * first accounted as iowait but then instead as idle. = scc->cpu_iowait; } else { scp->cpu_iowait = 0; } } if ((scc->cpu_idle < scp->cpu_idle)
20221010-2157) 01/21/2024 _x86_64_ (2 CPU) 05:26:43 PM CPU %usr %nice %sys %iowait 20221010-2157) 01/21/2024 _x86_64_ (2 CPU) 05:34:05 PM CPU %usr %nice %sys %iowait 0.00 0.00 0.00 28.26 0.00 0.00 71.01 05:35:47 PM CPU %usr %nice %sys %iowait 0.00 0.00 0.00 8.33 0.00 0.00 91.67 05:35:48 PM CPU %usr %nice %sys %iowait avg-cpu: %user %nice %system %iowait %steal %idle 0.83 0.00 0.30 0.24 15.17
显示版本信息 四、命令功能 监视系统输入输出设备和CPU的使用情况 五、常见用法 5.1 显示所有设备负载情况 # iostat avg-cpu: %user %nice %system %iowait %iowait:CPU等待输入输出完成时间的百分比。 %steal:管理程序维护另一个虚拟处理器时,虚拟CPU的无意识等待时间百分比。 %idle:CPU空闲时间百分比。 注意:如果%iowait的值过高,表示硬盘存在I/O瓶颈,%idle值高,表示CPU较空闲,如果%idle值高但系统响应慢时,有可能是CPU等待分配内存,此时应加大内存容量。 wkB/s avgrq-sz avgqu-sz await r_await w_await svctm %util avg-cpu: %user %nice %system %iowait wkB/s avgrq-sz avgqu-sz await r_await w_await svctm %util avg-cpu: %user %nice %system %iowait
实例 查看多核CPU核心的当前运行状况信息, 每2秒更新一次 mpstat 219:45:12 CPU %usr %nice %sys %iowait %irq %soft %steal %guest 99.87 如果要看每个cpu核心的详细当前运行状况信息,输出如下: mpstat -P ALL 2 19:43:58 CPU %usr %nice %sys %iowait ,nice值为负进程的CPU时间(%) (nice/total)*100 %sys 在internal时间段里,内核时间(%) (system/total)*100 %iowait 在internal时间段里,硬盘IO等待时间(%) (iowait/total)*100 %irq 在internal时间段里,硬中断时间(%) (irq/total)*100 +irq+softirq total_pre=pre_user+ pre_system+ pre_nice+ pre_idle+ pre_iowait+ pre_irq+ pre_softirq user
2.6.32-504.el6.x86_64 (idc1) 08/10/2021 _x86_64_ (8 CPU) 05:38:49 PM CPU %usr %nice %sys %iowait 2.6.32-504.el6.x86_64 (idc1) 08/10/2021 _x86_64_ (8 CPU) 05:54:17 PM CPU %usr %nice %sys %iowait 2.6.32-504.el6.x86_64 (idc1) 08/10/2021 _x86_64_ (8 CPU) 05:50:38 PM CPU %usr %nice %sys %iowait 0.50 0.00 0.00 0.00 0.00 0.00 98.00 05:50:40 PM CPU %usr %nice %sys %iowait :在internal时间段里,硬盘IO等待时间(%),值为(iowait/total)*100; irq:在internal时间段里,硬中断时间(%),值为(irq/total)*100; soft:在
x86_64 (ruioracle43) 02/23/2022 _x86_64_ (8 CPU) avg-cpu: %user %nice %system %iowait %iowait:CPU等待输入输出完成时间的百分比。如果%iowait的值过高,表示硬盘存在I/O瓶颈。 %steal:管理程序维护另一个虚拟处理器时,虚拟CPU的无意识等待时间百分比。 x86_64 (ruitest01) 08/18/2021 _x86_64_ (8 CPU) avg-cpu: %user %nice %system %iowait iowait表示的含义是cpu没在工作而在等待io的时间占比,在cpu高速运转的情况下也会出现iowait高的情况,这并不能表明磁盘性能就有问题。 如果%iowait的值过高,表示硬盘存在I/O瓶颈,%idle值高,表示CPU较空闲,如果%idle值高但系统响应慢时,有可能是CPU等待分配内存,此时应加大内存容量。
You can get the number of CPU ticks since boot from /proc/stat cat /proc/stat user nice system idle iowait processes executing in user mode system: processes executing in kernel mode idle: twiddling thumbs iowait idle CPU time from the total CPU time as follows: Total CPU time since boot = user+nice+system+idle+iowait +irq+softirq+steal Total CPU Idle time since boot = idle + iowait Total CPU usage time since boot =
64 (service-01) 11/15/2021 _x86_64_ (4 CPU) 03:00:24 PM CPU %usr %nice %sys %iowait 在internal时间段里,硬盘IO等待时间(%) (iowait/total)*100 %irq 在internal时间段里,硬中断时间(%) (irq/total)*100 %soft IO操作外的因为任何原因而空闲的时间闲置时间(%) (idle/total)*100 CPU总的工作时间计算方式: total_cur = user + system + nice + idle + iowait 64 (service-01) 11/15/2021 _x86_64_ (4 CPU) 03:00:49 PM CPU %usr %nice %sys %iowait 当 %iowait 数字较高时,一般当前负载下 I/O 子系统出现了某些问题。
+irq+softirq total_pre=pre_user+ pre_system+ pre_nice+ pre_idle+ pre_iowait+ pre_irq+ pre_softirq 在internal时间段里,硬盘IO等待时间(%) iowait/total*100 idle 在internal时间段里,CPU除去等待磁盘IO操作外的因为任何原因而空闲的时间闲置时间 (%) idle/total*100 total_cur=user+system+nice+idle+iowait+irq+softirq total_pre=pre_user+ pre_system+ : %user %nice %sys %iowait %idle 7. sar sar是System Activity Reporter(系统活跃情况报告)的缩写。 在internal时间段里,硬盘IO等待时间(%) iowait/total*100 idle 在internal时间段里,CPU除去等待磁盘IO操作外的因为任何原因而空闲的时间闲置时间 (%)
1127.18.2.el7.x86_64 (centos7) 03/28/2021 _x86_64_ (1 CPU) 11:14:29 AM CPU %usr %nice %sys %iowait internal时间段里,nice值为负进程的CPU时间(%)(nice/total)*100 %sys #在internal时间段里,内核时间(%)(system/total)*100 %iowait #在internal时间段里,硬盘IO等待时间(%) (iowait/total)*100 %irq #在internal时间段里,硬中断时间(%)(irq/total)*100
cpu_times CPU运行时间 psutil.cpu_times() scputimes(user=125.65, nice=20.8, system=243.42, idle=5515413.34, iowait 的信息 psutil.cpu_times(percpu=True) scputimes(user=18.38, nice=1.51, system=95.18, idle=689387.87, iowait steal=0.0, guest=0.0, guest_nice=0.0), scputimes(user=9.84, nice=3.23, system=7.0, idle=689816.01, iowait steal=0.0, guest=0.0, guest_nice=0.0), scputimes(user=8.84, nice=1.94, system=6.57, idle=689669.6, iowait steal=0.0, guest=0.0, guest_nice=0.0), scputimes(user=4.52, nice=0.0, system=19.14, idle=689599.71, iowait