今天繼續拜讀「深入淺出計算機組成原理」專欄,覺得講 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 左右。
這個 100 應該是這么計算的,首先我們假設是一個 每分鍾 7200 轉的 HDD 盤
在隨機讀取的情況下,每轉半圈大概可以找到一個目標幾何區 也就是每分鍾可以轉 240 個半圈
1s/240 = 4.17 這是平均延時(Average Latency)
另外我們還需要進行尋道,在盤面旋轉之后我們懸臂定位到指定扇區的時間,現在 HDD 盤平均尋道時間在 4-10ms
所以我們平均每 4.17 + 4 - 4.17 + 10 = 8 - 14 ms 完成一次數據存取。
那么對應 IOPS 就是 70 - 125 ,平均一下 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
