https://zhuanlan.zhihu.com/p/407333624

原创:小姐姐味道(微信公众号ID:xjjdog),欢迎分享,转载请保留出处。

我们经常遇到iowait这个名词,在top命令中,vmstat中,sar命令中,都有它的身影。很多同学按照经验,当看到iowait非常高的时候,一般判定为磁盘I/O有瓶颈,但这并不完全正确。 io并不是一个可靠值。

比如下面几个问题。

  1. iowait处于100%时,还能够运行其他CPU密集型应用么?
  2. iowait处于90%以上,就一定证明io有问题么?
  3. iowait占用非常少时,就一定证明io没问题么?

1. 数值来自哪?

上面提到的这些监控工具,看起来监控的值包容万象,但这些数字都不是它们去算的。这些数字,静悄悄的躺在内存文件系统/proc/stat中,而进程的数据,躺在/proc/${pid}/stat中。但是如果不经过这些工具的加工,我们去辨识这些数值的话,是由难度的。

在info命令中,可以看到iowait的解释。

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

解释模糊不清,但显然是和磁盘I/O有关的。这里没有提到网络I/O,所以和网络I/O关系不大,但与网络文件系统如NFS等密切相关。

每一个cpu都会有下多种状态中的一个。

  • user 处于用户态进程执行
  • sys 处于系统态内核执行
  • idle 处于空闲状态,但不证明cpu不运行,由于处于空转状态,所以能耗特别低
  • iowait 处于等待I/O的状态

总体上,遵循下面的公式。

CPU时间=user+sys+nice+idle+iowait+irq+softirq+steal

从字面上的意思来看,iowait像是一直阻塞在那里等待I/O操作完成,但实际情况是,CPU并不会做这种无谓的等待,它只是反映了等待I/O完成的一个比例。

为什么CPU不会等待磁盘I/O呢?因为磁盘实在是太慢了,磁盘上的文件块,读入内核缓冲区的这个过程,是交给DMA去做的。cpu只是响应一下中断,就进入了被中断完成的唤醒状态。此时,如果有新的任务到来,这些cpu资源依然能够挪动身躯去做。

内核会周期性的记录这些统计数据,它首先判断cpu是不是空闲的,如果不是,则判断是在内核态还是用户态;如果不是,则会判断是否有磁盘I/O请求被当前的CPU发起,如果有则增加iowait的值,如果没有则增加idle的值。

sar等命令,会读取/proc/stat中的数据,进行二次加工。由于sar本身也有一个刷新频率,所以它展现的是统计值。

2. 从现象看本质

为了弄清楚iowait的表现,我们来看几个例子。

案例1

假如我们写了一个小型的数据库,运行在1核的机器上。这个数据库,会使用cpu计算一些数据,花费10ms,然后同步写入磁盘,花费20ms,那么整个操作下来,要花费30ms,也就是tps = 33。此时,iowait就是66%,而user就是33%。

而如果换成了ssd,写磁盘只花费了1ms。那么此时的tps = 90,iowait就变成了 8%左右。

案例2

我们再来想想一下,现在cpu计算数据的过程,换成了dd命令,它不会做过多的计算,几乎不耗费时间,此时,写磁盘依然花费1-2ms的时间,我们的tps达到了500-1000左右。iowait增加了,但我们的吞吐量竟然也增加了,可以说工作的更好。

案例3

现在考虑另外一种相反的极端情况。我们的应用cpu产生文件只需要1ms,但写入磁盘需要1秒。那么此时iowait会达到99%左右。此时,我们再启动另外一个进程,它是一个死循环,会耗尽所有的CPU资源。这个进程一加入,就抢占了空闲的CPU时间片。现在去看系统显示,iowait的状态会降低到接近0,idle的状态也会接近0。但这可怜的系统,此时并不是没有问题,因为我们的磁盘,可一直是在I/O操作之中。

100%的iowait没有问题,但1%的iowait问题却很大。

参考:https://blog.pregos.info/wp-content/uploads/2010/09/iowait.txt

由于多核的参与,事情会更复杂。因为iowait是个统计值,sar等命令直接观测的也是多个核数的统计值,所以在两台机器上运行良好的程序,指标的显示也会相差很大。

关键就在于,iowait和idle是一个此消彼长的关系,它们两个加起来,就是系统目前可以被使用的cpu时间片。iowait过高,不代表它不能够运行其他计算性任务了,其他的进程或者线程,还能够继续运行。我更愿意把iowait认为是idle的一部分,这样更容易理解一些。

3. 经验来源

那iowait过高,磁盘有问题,这个印象是怎么养成的呢?

原因还是由于IO资源的规划问题。假如你的系统写了非常非常多的日志,此时iowait应该是跑满了。假如你用的是同步写日志的方式(大多数都是),那么大多数线程就要等待这些繁忙的I/O请求。这个等待,是真的等待,因为这些线程在磁盘写成功之前,什么都干不了。以tomcat默认200个线程为例,请求量一增加,就全部占满了,进入了BLOCKED状态。

此时的应用反应是:应用几乎什么都响应不了。机器上的其他进程,也响应缓慢。但是注意,应用的线程不能运行了,不代表其他应用的线程不能运行。线程处于BLOCKED状态,并不会占用CPU。只要多加一块磁盘,和其他磁盘隔离开来,就能解决问题。

xjjdog这里抛出一个遇到过的极品问题。

ElasticSearch 的速度是非常快的,我们为了压榨它的性能,对磁盘的读写几乎是全速的。它在后台做了很多 Merge 动作,将小块的索引合并成大块的索引。还有 TransLog 等预写动作,都是 I/O 大户。

问题是,我们有一套 ES 集群,在访问高峰时,有多个 ES 节点发生了严重的 STW 问题。有的节点竟停顿了足足有 7~8 秒。

 [Times: user=0.42 sys=0.03, real=7.62 secs]

从日志可以看到在 GC 时用户态只停顿了 420ms,但真实的停顿时间却有 7.62 秒。盘点一下资源,唯一超额利用的可能就是 I/O 资源了(%util 保持在 90 以上),GC 可能在等待 I/O。

原因就在于,写 GC 日志的 write 动作,是统计在 STW 的时间里的。在我们的场景中,由于 ES 的索引数据,和 GC 日志放在了一个磁盘,GC 时写日志的动作,就和写数据文件的动作产生了资源争用。

解决方式也是比较容易的,把 ES 的日志文件,单独放在一块普通 HDD 磁盘上就可以了。所以在这种情况下,iowait不变,却能解决问题。

End

问题是,现在的很多企业,已经上了docker等虚拟化环境,iowait就更成为一个操蛋的指标。Linux的8种namespace:挂载点、进程、网络、ipc、uts、user、cgroup、time等。其中,cgroup能限额cpu、限额内存、限额磁盘容量,也能限额磁盘io,限制磁盘的读写iops,这会让本身就慢的磁盘用起来更慢。但如果不限制io,完全放开,对于宿主机的磁盘使用,大家就会哄抢,就要看运气!所以限制业务无限制的日志io需求,一直在进行中。

电池和磁盘技术,可真是限制科技发展的两大枷锁啊。

作者简介:小姐姐味道 (xjjdog),一个不允许程序员走弯路的公众号。聚焦基础架构和Linux。十年架构,日百亿流量,与你探讨高并发世界,给你不一样的味道。我的个人微信xjjdog0,欢迎添加好友,进一步交流。

推荐阅读:

1. 玩转Linux
2. 什么味道专辑

3. 蓝牙如梦
4. 杀机!

[转帖]宁可信鬼,也不信 iowait 这张嘴!的更多相关文章

  1. 【初窥javascript奥秘之事件机制】论“点透”与“鬼点击”

    前言 最近好好的研究了一番移动设备的点击响应速度,期间不断的被自己坑,最后搞得焦头烂额,就是现在可能还有一些问题,但是过程中感觉自己成长不少, 最后居然感觉对javascript事件机制有了更好的认识 ...

  2. jdk和jre是什么?都有什么用?(转帖)

    jdk和jre是什么?都有什么用?(转帖) 文章分类:Java编程 大家肯定在安装JDK的时候会有选择是否安装单独的jre,一般都会一起安装,我也建议大家这样做.由于这样更能帮助大家弄清楚它们的差别: ...

  3. IT人为什么难以拿到高薪?【转帖】

    最近在论坛里看到很多人发牢骚,说薪水少,可在我看来,你们这样的人拿得到高薪才怪! 我先问一句:这里有多少人是本科的?有多少人是正规本科的(不算自考,成考和专升本)?有多少人是有学位的?有多少有学位的是 ...

  4. [转帖]nginx配置ssl加密(单/双向认证、部分https)

    nginx配置ssl加密(单/双向认证.部分https) https://segmentfault.com/a/1190000002866627   nginx下配置ssl本来是很简单的,无论是去认证 ...

  5. (非原)SQL注入专题--整理帖 && like 语句拼sql 如何防止注入攻击。

    原地址:blog.csdn.net/lvjin110/article/details/28697695 like 语句拼sql 如何防止注入攻击?http://bbs.csdn.net/topics/ ...

  6. IIS部署SSL证书后提示不可信的解决方案

    IIS部署SSL证书后提示不可信的解决方案   本帖最后由 wosign-support3 于 2015-7-17 17:18 编辑 第一步:打开mmc——点击文件——添加删除管理单元——证书——计算 ...

  7. 【转帖】 解开龙芯与mips4000的关系

    -- 苏联给的套件,我们只要把电子管插上就好. -- 千万次机器,不晓得来源 DJS-130系列,16位小型机,仿造美国NOVA DJS-180系列,超级小型机,仿造美国DEC VAX, 能跑DEC的 ...

  8. %iowait和CPU使用率的正确认知

    resources 理解 %IOWAIT (%WIO) LINUX系统的CPU使用率和LOAD Linux Performance Observability Tools How Linux CPU ...

  9. nginx负载均衡基于ip_hash的session粘帖

    nginx负载均衡基于ip_hash的session粘帖 nginx可以根据客户端IP进行负载均衡,在upstream里设置ip_hash,就可以针对同一个C类地址段中的客户端选择同一个后端服务器,除 ...

  10. APIJSON,让接口见鬼去吧!

    我: APIJSON,让接口见鬼去吧! https://github.com/TommyLemon/APIJSON 服务端: 什么鬼? 客户端: APIJSON是啥? 我: APIJSON是一种JSO ...

随机推荐

  1. 理论+示例,详解GaussDB(DWS)资源管理

    摘要:合理地管理和分配系统资源,是保证数据库系统稳定高效运行的关键. 本文分享自华为云社区<GaussDB(DWS)资源管理能力介绍与应用示例>,作者: 门前一棵葡萄树 . 一.资源管理能 ...

  2. 一文带你掌握Redis操作指南

    摘要:Redis是一种支持Key-Value等多种数据结构的存储系统. Redis是一种支持Key-Value等多种数据结构的存储系统.可用于缓存,事件发布或订阅,高速队列等场景.该数据库使用ANSI ...

  3. 科技抗疫,少年可期,为这群有AI的天使开发者疯狂打call

    摘要:2020年初新冠突发,在这场抗疫的战斗中,让我们深刻体会到,疫情与每一个人息息相关.有这样一群来自华中科技大学的师生项目团队,他们利用AI技术,助力全球抗疫,他们是怎么做的呢?让我们一起来看看吧 ...

  4. 详解openGauss多线程架构启动过程

    摘要:本文介绍openGauss数据库的启动过程,包括主线程,辅助线程及业务处理线程的启动过程. 本文分享自华为云社区<openGauss内核分析(一):openGauss 多线程架构启动过程详 ...

  5. 漏洞评分高达9.8分!Text4Shell 会是下一个 Log4Shell吗?

    在过去的几天里,Apache Commons Text 库中一个名为 Text4Shell 的新漏洞引起很大的轰动,该漏洞存在于 Apache Commons Text 1.5到1.9版本中.此警报于 ...

  6. 火山引擎 ByteHouse:如何提升 18000 节点的 ClickHouse 可用性?

    更多技术交流.求职机会,欢迎关注字节跳动数据平台微信公众号,回复[1]进入官方交流群 ClickHouse 是业内被广泛使用的 OLAP 引擎.当集群规模过大时,ClickHouse 则面临使用局限性 ...

  7. 企业诊断屋:二手车交易平台 APP 如何用 AB 测试赋能业务

    更多技术交流.求职机会,欢迎关注字节跳动数据平台微信公众号,回复[1]进入官方交流群 2023年汽车行业新车市场低靡,由新车降价引发的车辆价格波动很快传导到二手车市场,二手车的交易也受到了冲击,收车验 ...

  8. Axure 自定义元件库

    点击文件 -> 新建元件库 可以添加多个元件,并将期重命名 保存元件库 新建页面 添加元件,选择自建的元件库 导入后就会发现我的原件库 这样就可以使用我们自定义的元件库了

  9. 将文件从windows格式改为linux格式

    1.使用notepad++软件转换 notepad++官方下载地址 使用notepad++打开文件---编辑---文档格式转换---转为unix---上传至linux 2.set ff vim 文件, ...

  10. ME21N 采购订单批导

    1业务场景 事务代码:ME21N创建采购订单 可以通过BAPI_PO_CREATE1批量创建 2代码实现 1.抬头 2.行项目 3.增强 抬头增强字段放在BAPI_TE_MEPOHEADER结构中的C ...