今天继续拜读「深入浅出计算机组成原理」专栏,觉得讲 IO_WAIT 这篇很有意思,正好可以结合前面的一篇讲物理硬件存速度的一块儿看。
现在我们看硬盘厂商出品的性能报告,通常会看到两个指标,一个是响应时间(Response Time) 另外一个是 数据传输速率 (Data Transfer Rate) 。
目前硬盘分两种,一种是 HDD 硬盘,也就是传统的机械硬盘.使用的是传统的 SATA3.0 的接口,而另外一种是 SSD 盘,也就是现在被我们成为固态硬盘的东西。它既可以使用 SATA3.0 接口,还可以使用另外一种叫做 PCI EXPRESS 的接口(以下称为 PCI 接口)。这里要补充一下 PCI 接口的吞吐率大幅高于 SATA3.0 的接口。 使用 SATA3.0 口的固态硬盘可能面临 接口的传输速率极限而限制了硬盘本身读写速度的发挥。
现在我们 SATA3.0 的贷款大致是 6Gbit/s 也就是 6 * 1024 / 8 约768 MB/s 的速度。这是一个很高的理论带宽值,根据专栏提供的数据,我们平时使用传输速率差不多只有 200MB/s
这里我插入一个 访问延时的比较图
这是我们平时经常接触的存储器的访问延时情况,可以看到 上面提到的 HDD 和 SSD 盘是最便宜的两种,随机访问延时 SSD 差不多是 150 微秒, HDD 则已经到毫秒级别。速度越快的存储,存量越小,越贵。
下面我们继续回到 HDD 和 SSD 这种通用外部存储上来。这里有一张使用 PCI 接口的 SSD 传输图
第一行参数 Seq 代表 SSD 进行顺序读写时候的速度,可以看到 - - 真是非常快啊。
第二行 4k 代表对 4k 大小文件进行随机读写的效率。可以看到- - 真是非常慢啊,对比 seq 的速度真是慢了不知道多少。
第三行 4K-64 64thrd表示多线程并发操作的性能,一般个人使用情况下不会用到如此多线程,一般也就qd=3,但是这个指标对服务器应用很重要。
第四行 acc代表我们之前说的响应时间可以看到 0.066ms ,还记得我们上面的随机读取延时图吗,就跟这个时间差不多。
另外还有一个指标也是衡量吞吐量很重要的指标, IOPS(每秒读写次数)
比如随机读写,我们随机读性能是 40MB/S 那么我们读 4kb 文件
40*1024 / 4 ~= 10000 IOPS 写入差不多 20000
因为我们在实际应用的开发中,对于数据的访问,更多的是随机读写,而不是顺序读写。我们平时说的服务器承受的 “并发”,其实是在说,会有很多个不同的进程和请求来访问服务器。自然,它们在硬盘*问的数据,是很难顺序放在一起的。在这种情况下,随机读写的 IOPS 才是服务器性能的核心指标。
根据专栏给出的数据,正常的 HDD IOPS 仅有 100 左右。
上面介绍了那么多如何衡量硬盘的读写,下面我们来回归到主题,如何定位 IO_WAIT
使用
top
top - 06:26:30 up 4 days, 53 min, 1 user, load average: 0.79, 0.69, 0.65 Tasks: 204 total, 1 running, 203 sleeping, 0 stopped, 0 zombie %Cpu(s): 20.0 us, 1.7 sy, 0.0 ni, 77.7 id, 0.0 wa, 0.0 hi, 0.7 si, 0.0 st KiB Mem: 7679792 total, 6646248 used, 1033544 free, 251688 buffers KiB Swap: 0 total, 0 used, 0 free. 4115536 cached Mem
第三行 wa 就代表 cpu 的 io_wait 情况。这里可以用把这些简写都大概介绍一下
us:用户占用 cpu 比例
sy:内核空间占用 cpu 比例
ni:用户进程空间内改变过优先级的进程占用CPU百分比
id:空闲CPU百分比
wa: 等待 io 的 cpu 时间占比
hi:硬件中断
si:软件中断
st: 不知道是啥- - 不知道做什么用
如果我们看到 wa 非常高,说明 cpu 等待 io 的情况比较严重。如果我们发现了 wa 很高可以继续执行 iostat 查看详情。
iostat
Linux 3.10.0-514.21.1.el7.x86_64 (iZ2ze3vworsqn8xb3m9zn5Z) 09/26/2019 _x86_64_ (8 CPU) avg-cpu: %user %nice %system %iowait %steal %idle 1.02 0.00 0.59 0.21 0.00 98.18 Device: tps kB_read/s kB_wrtn/s kB_read kB_wrtn vda 18.59 29.85 200.15 1033068029 6926347580 vdb 0.23 5.13 78.92 177419637 2731053200
这是一台我部署了 kafka 的机器执行 iostat 的情况。
可以看到 iowait 的情况,以及单个磁盘 tps(iops)的情况。这时候我们要找出到底是哪个程序这么吃 io 我们使用
iotop
注意 iotop 在 CentOS7.X 版本上好像不是默认安装的,可以安装一下 yum -i install iotop
Total DISK READ : 0.00 B/s | Total DISK WRITE : 15.75 K/s Actual DISK READ: 0.00 B/s | Actual DISK WRITE: 35.44 K/s TID PRIO USER DISK READ DISK WRITE SWAPIN IO> COMMAND 104 be/3 root 0.00 B/s 7.88 K/s 0.00 % 0.18 % [jbd2/sda1-8] 383 be/4 root 0.00 B/s 3.94 K/s 0.00 % 0.00 % rsyslogd -n [rs:main Q:Reg] 1514 be/4 www-data 0.00 B/s 3.94 K/s 0.00 % 0.00 % nginx: worker process
如果有应用一直在前排 且 IO> 一直非常大,我们可以从 COMMAND 列定位到该程序进行查看。
以上。
Ref:
https://blog.csdn.net/Sasoritattoo/article/details/9318893 CPU状态信息us,sy,ni,id,wa,hi,si,st含义
https://serverfault.com/questions/155882/wa-waiting-for-i-o-from-top-command-is-big wa (Waiting for I/O) from top command is big
https://time.geekbang.org/column/article/113809 极客时间「深入浅出计算机组成原理」44讲「理解 IO_WAIT」: I/O 性能到底是怎么回事儿?
https://en.wikipedia.org/wiki/IOPS