服务器之家:专注于服务器技术及软件下载分享
分类导航

Linux|Centos|Ubuntu|系统进程|Fedora|注册表|Bios|Solaris|Windows7|Windows10|Windows11|windows server|

服务器之家 - 服务器系统 - Linux - 聊一聊被众人误解许久的 iowait

聊一聊被众人误解许久的 iowait

2023-05-18 18:07未知服务器之家 Linux

来源:PostgreSQL学徒 1 了解 Linux IOWait 我见过许多 Linux 性能工程师将 CPU 使用率中的 IOWait 部分看作是表明系统何时受到 I/O 限制 的东西。在这篇博客中,我将解释为什么这种方法不可靠以及可以使用哪些更好的指标。 让我们从运行

来源:PostgreSQL学徒

1了解 Linux IOWait

我见过许多 Linux 性能工程师将 CPU 使用率中的 "IOWait" 部分看作是表明系统何时受到 I/O 限制

的东西。在这篇博客中,我将解释为什么这种方法不可靠以及可以使用哪些更好的指标。

让我们从运行一个小实验开始——在系统上产生大量的 I/O 使用:

sysbench--threads=8--time=0--max-requests=0fileio--file-num=1--file-total-size=10G--file-io-mode=sync--file-extra-flags=direct--file-test-mode=rndrdrun

Percona 监控和管理 (PMM) 中的 CPU 使用情况:

聊一聊被众人误解许久的 iowait

root@iotest:~#vmstat10
procs-----------memory-------------swap-------io-----system--------cpu-----
rbswpdfreebuffcachesisobiboincsussyidwast
36071371522645276297200405001714251946931655353
280713810026476762964003449711720059378653137735
080713916026500763016003474483720599379354175723
270713973626524762968003347301419190362563154716
44071394842653676290000253995615230279342116774
07071394842653676290000350854620777383452133775

到目前为止,一切顺利,而且——我们看到 I/O 密集型工作负载明显对应于高 IOWait(vmstat 中的 "wa" 列)。

让我们继续运行我们的 I/O 密集型工作负载并添加一个繁重的 CPU 密集型工作负载:

sysbench--threads=8--time=0cpurun

聊一聊被众人误解许久的 iowait

root@iotest:~#vmstat10
procs-----------memory-------------swap-------io-----system--------cpu-----
rbswpdfreebuffcachesisobiboincsussyidwast
124071216402683276347600480341460289554436747373
13307120416268567634640025646414124042593769150016
880712102026880763496003257891615788333838515000
1060712146426904763460003229543316025334618315001
970712359226928763524003367941416772349078515001
1330712413226940763556003863841017704386798416000
970712825226964763604003561981316303352758415000
970712805226988763584003247231413905308988015005
1060712202027012763584003804291616770370798118001

发生了什么?IOWait 完全消失了,现在这个系统看起来完全不受 I/O 限制了!

当然,实际上,我们的第一个工作负载没有任何变化——它仍然是 I/O 密集型的;当我们查看 "IOWait" 时,它就变得不可见了!

要理解发生了什么,我们真的需要了解 "IOWait" 是什么以及它是如何计算的。

有一篇很好的文章(译文在后面)对这个主题进行了更详细的介绍,但基本上,"IOWait" 是一种空闲 CPU 时间。如果 CPU 核心因为没有工作要做而空闲,则该时间被计为 "idle"。但是,如果它因为某个进程在磁盘上等待而空闲,则 I/O 时间将计入"IOWait"。

但是,如果一个进程正在等待磁盘 I/O 但系统上的其他进程可以使用 CPU,则该时间将作为用户态/系统态时间计入到它们的 CPU 使用率。

由于这种计算方式,其他有趣的行为是可能的。现在我们不再运行八个 I/O 密集型线程,而是在四核 VM 上运行一个 I/O 密集型进程:

sysbench--threads=1--time=0--max-requests=0fileio--file-num=1--file-total-size=10G--file-io-mode=sync--file-extra-flags=direct--file-test-mode=rndrdrun

聊一聊被众人误解许久的 iowait

procs-----------memory-------------swap-------io-----system--------cpu-----
rbswpdfreebuffcachesisobiboincsussyidwast
310713030827704763592006200012450385773569203
210712714427728763592006709814481092532570202
210712844827752763592007276015517999462572201
400713306827776763588006956629495395622572211
210713132827800763576006750115479392762572201
200712813627824763592005946115431682722571203
310712971227848763592006413913462888542570203
200712898427872763592007102718506897182671201
100712823227884763592006977912496795492571201
500712850427908763592006641918476791392571201

尽管这个进程完全是 I/O 密集型的,但我们可以看到 IOWait (wa) 不是特别高,不到 25%。在具有 32、64 或更多内核的大型系统上,这种完全出现 IO 瓶颈的进程几乎是不可见的,会产生个位数的 IOWait 百分比。

因此,高 IOWait 表明系统中有许多进程在等待磁盘 I/O,但即使 IOWait 低,磁盘 I/O 也可能成为系统上某些进程的瓶颈。

如果 IOWait 不可靠,你可以使用什么来提供更好的可见性?

首先,看一下特定应用的可观察性。应用程序,如果它被很好地检测,往往最清楚什么时候它被磁盘约束,以及什么特定的任务被 I/O约束。

如果你只能访问 Linux 指标,请查看 vmstat 中的 "b"列,它对应于磁盘 I/O 上阻塞的进程。这将显示此类进程,即使是并发的 CPU 密集型负载,也会屏蔽 IOWait:

聊一聊被众人误解许久的 iowait

聊一聊被众人误解许久的 iowait

最后,你可以查看每个进程的统计信息以了解哪些进程正在等待磁盘 I/O。

以上译自 https://www.percona.com/blog/understanding-linux-iowait/

2什么是 iowait 以及它如何影响 Linux 性能

I/O 等待或者 iowait、wait、wa、%iowait 或 wait% 通常由 top、sar、atop 等 Linux 命令行系统监控工具显示。就其本身而言,它是让我们深入窥探 Linux 系统性能的众多性能统计数据之一。

最近与一位新客户的交谈中提到了 I/O 等待。在我们的支持电话中,他们报告说他们的 32 CPU 核心系统上的负载峰值为 60 到 80。这导致了页面加载缓慢、超时和间歇性中断。原因呢?存储 I/O 瓶颈最初是由持续高的 iowait 所表示,后来通过额外调查得到证实。

什么是 I/O 等待?I/O 等待是如何影响 Linux 服务器性能的?我们如何监控和减少与 I/O 等待相关的问题?继续阅读以寻找这些问题的答案。

聊一聊被众人误解许久的 iowait

3什么是 I/O 等待?

I/O 等待适用于 Unix 和所有基于 Unix 的系统,包括 macOS、FreeBSD、Solaris 和 Linux。

I/O 等待 (iowait) 是 CPU(或多个 CPU)空闲的时间百分比,在此期间系统有待处理的磁盘 I/O 请求。(来源:man sar)top man 手册页给出了这个简单的解释:"I/O 等待 = 等待 I/O 完成的时间。" 换句话说,I/O 等待的存在告诉我们系统空闲时它可以处理未完成的请求。

"iowait shows the percentage of time that the CPU or CPUs were idle during which the system had an outstanding disk I/O request." – iostat man page.

在使用 Linux top 和其他工具时,你会注意到 CPU(及其核心)在以下状态下运行:us(用户态)、sy(内核态)、id(空闲)、ni(nice)、si(软中断)、hi(硬中断)、st(steal)和 wa(等待)。其中,用户态、内核态、空闲状态和等待状态的值加起来应为 100%。请注意,"idle" 和 "wait" 是不同的。"idle" CPU 表示没有工作负载存在,而另一方面,"wait" (iowait) 表示 CPU 何时处于空闲状态等待未完成的请求。

如果 CPU 空闲,内核将确定任何来自 CPU 的未完成 I/O 请求(比如 SSD 或 NFS)。如果有,则 "iowait" 计数器递增。如果没有任何待处理的请求,则 "idle" 计数器会增加。

4I/O 等待和 Linux 服务器性能

值得注意的是, iowait 有时可以指示吞吐量瓶颈,而在其他时候,iowait 可能完全没有意义。有可能拥有高 iowait 的健康系统,但也可能有完全没有 iowait 的存在瓶颈的系统。

I/O 等待只是 CPU / CPU 核心的指示状态之一。高 iowait 意味着你的 CPU 正在等待请求,但你需要进一步调查以确认来源和影响。

例如,服务器存储(SSD、NVMe、NFS 等)几乎总是比 CPU 性能慢。因此,I/O 等待可能会产生误导,尤其是涉及到随机读/写工作负载时。这是因为 iowait 仅测量 CPU 性能,而不测量存储 I/O。

虽然 iowait 表明 CPU 可以处理更多的工作负载,但根据服务器的工作负载以及负载如何执行计算或使用存储 I/O,并不总是可以解决 I/O 等待。或者实现接近于零的值是不可行的。

根据最终用户体验、数据库查询健康状况、事务吞吐量和整体应用程序健康状况,你必须决定报告的 iowait 是否表明 Linux 系统性能不佳。

例如,如果你看到 1% 到 4% 的低 iowait,然后将 CPU 升到 2 倍的性能,iowait 也会增加。具有相同存储性能的 2 倍更快的 CPU = ~ 2 倍的等待时间。你需要考虑你的工作负载来确定应该首先关注哪些硬件。

5监控和减少 I/O 等待相关问题

聊一聊被众人误解许久的 iowait

让我们看看一些用于监视 Linux 上的 I/O 等待的有价值的工具。

  • atop – 使用 -d 选项运行它或按 d 切换磁盘统计视图。
  • iostat – 尝试使用 -xm 2 选项进行扩展统计,以兆字节为单位,以两秒为间隔。
  • iotop – 类似 top 的 I/O 监视器。尝试使用 -oPa 选项来仅显示活动进程的累积 I/O。
  • ps – 使用 auxf,那么在"STAT"列下,"D"通常表示磁盘 iowait。
  • strace - 查看进程执行的实际操作。参阅 strace man 手册。
  • lsof – 确定你负责的进程后,使用 -p [PID] 查找特定文件。

减少 I/O 等待相关问题

采取以下步骤减少与 I/O 等待相关的问题。

  • 优化应用程序的代码和数据库查询。这可以大大降低磁盘读/写的频率。这应该是你的第一个方法,因为应用程序越高效,在硬件上的长期花费就越少。另请参阅:100 应用程序性能监控 (APM) 和可观察性解决方案。
  • 使 Linux 系统和软件版本保持最新。这不仅对安全性更好,而且通常情况下,最新支持的版本会提供显着的性能改进,无论是 Nginx、Node.js、PHP、Python 还是 MySQL。
  • 确保有空闲的可用内存。足够的空闲内存,以便大约一半的服务器内存用于内存缓冲区和缓存,而不是交换和换页到磁盘。当然,这个比例会因情况而异。因此,请确保你没有交换,并且内核缓存压力不会因缺少可用内存而变高。
  • 调整系统、存储设备和 Linux 内核以提高存储性能和使用寿命。
  • 最后,如果一切都失败了:将存储设备升级到更快的 SSD、NVMe 或其他高吞吐量存储设备。

6结论

iowait 统计数据是一个有用的性能统计数据,可用于监控 CPU 利用率健康状况。当 CPU 空闲并且可以执行更多计算时,它会通知系统管理员。然后,我们可以使用可观察性、基准测试和跟踪工具(例如上面列出的那些工具)来综合了解系统的整体 I/O 性能。你的主要目标应该是消除因等待磁盘、NFS 或其他与存储相关的 I/O 而直接导致的任何 iowait。

以上译自

7小结

这篇文章是今天上午老板在群里分享的,我看到后十分有感触,因为我之前阅读过类似的文章,知晓 iowait 这个参数的坑,Linux 中的解释是

Show the percentage of time that the CPU or CPUs were idle during which the system had an outstanding disk I/O request.

也就是说 CPU 在等待磁盘 I/O 请求时,处于空闲状态的时间百分比(此时正在运行着 idle 进程,空闲的时候也会运行一个进程)。

可以看出,如果系统处于 iowait 状态,那么必须满足以下两个条件:

  1. 系统中存在等待 I/O 请求完成的进程。
  2. 系统当前正处于空闲状态,也就是说没有可运行的进程。

主要代码流程如下

voidaccount_process_tick(structtask_struct*p,intuser_tick)
{
cputime_tone_jiffy_scaled=cputime_to_scaled(cputime_one_jiffy);
structrq*rq=this_rq();

//1.如果当前进程处于用户态,那么增加用户态的CPU时间
if(user_tick){
account_user_time(p,cputime_one_jiffy,one_jiffy_scaled);
}
//2.如果前进程处于内核态,并且不是idle进程,那么增加内核态CPU时间
elseif((p!=rq->idle)||(irq_count()!=HARDIRQ_OFFSET)){
account_system_time(p,HARDIRQ_OFFSET,cputime_one_jiffy,
one_jiffy_scaled);
}
//3.如果当前进程是idle进程,那么调用account_idle_time()函数进行处理
else{
account_idle_time(cputime_one_jiffy);
}
}

voidaccount_idle_time(cputime_tcputime)
{
structcpu_usage_stat*cpustat=&kstat_this_cpu.cpustat;
cputime64_tcputime64=cputime_to_cputime64(cputime);
structrq*rq=this_rq();

//1.如果当前有进程在等待IO请求的话,那么增加iowait的时间
if(atomic_read(&rq->nr_iowait)>0){
cpustat->iowait=cputime64_add(cpustat->iowait,cputime64);
}
//2.否则增加idle的时间
else{
cpustat->idle=cputime64_add(cpustat->idle,cputime64);
}
}

也就是说:

  1. 如果当前有进程在等待 I/O 请求的话,那么增加 iowait 的时间。
  2. 如果当前没有进程在等待 I/O 请求的话,那么增加 idle 的时间。

所以正确解释是:有进程在等待 IO,被阻塞了,并且当前系统是空闲的,没有其他进程在运行。

怎么样?各位是不是涨知识了?又比如经常被用来判断磁盘饱和度的 %util 指标,各位可能会在不少文章中看到类似结论:

如果 %util 接近 100%,说明产生的I/O请求太多,I/O系统已经满负荷,该磁盘可能存在瓶颈。

这个结论也是不严谨的,%util 表示该设备有I/O(即非空闲)的时间比率,不考虑 I/O 有多少,只考虑有没有。由于现代硬盘设备都有并行处理多个 I/O 请求的能力,所以 %util 即使达到 100% 也不意味着设备饱和了。举个简化的例子:某硬盘处理单个 I/O 需要0.1秒,有能力同时处理 10 个I/O 请求,那么当 10 个 I/O 请求依次顺序提交的时候,需要 1 秒才能全部完成,在 1 秒的采样周期里 %util 达到 100%;而如果 10 个 I/O 请求一次性提交的话,0.1 秒就全部完成,在 1 秒的采样周期里 %util 只有 10% 。可见,即使 %util 高达 100%,硬盘也仍然有可能还有余力处理更多的 I/O 请求,即没有达到饱和状态。很可惜,iostat 并没有用来判断饱和度的指标。

所以,阅读此文后,千万不要再凭借看到一个 iowait 高指标就判断 IO 瓶颈了。


延伸 · 阅读

精彩推荐