概述
在性能測試中,IO 是一個非常重要的指標。我這里整理了一部分關於 IO 的內容,用來加深自己的印象。
所謂 IO,其實就是磁盤的讀寫。讀 IO,就是發出指令,從磁盤讀取某段扇區的內容。指令首先告訴磁盤開始的扇區位置,然后給出需要從這個初始扇區往后讀取的連續扇區的個數,同時會告知磁盤動作是讀,還是寫。磁盤收到指令之后就會按照指令的要求,讀或者寫數據。控制器發出指令+數據讀/寫,就是一次 IO。
IO 大小
IO 大小指的是指令給出的連續讀取扇區數目的多少。如果數目很大,比如 128k,64k 等等,算是大塊 IO,如果很小,比如 1k, 4k 等等,算是小塊 IO。
注:
平均 IO 尺寸=吞吐量/IO 數目;
吞吐量/硬盤傳輸數據的速度:傳輸數據=讀出數據 + 寫入數據
IOPS(每秒 IO 數):一次磁盤的連續讀或連續寫稱為一次磁盤 IO。IOPS 表示磁盤每秒連續讀和連續寫次數
IO 模式
連續/隨機 IO
連續和隨機,取決於本次 IO 的初始扇區地址,和上一次 IO 的結束扇區地址是否連續。如果是,則本次 IO 是一個連續 IO;如果不連續,算一次隨機 IO。
連續 IO:因為本次初始扇區和上次結束扇區相隔很近,則磁頭幾乎不用換道或換道時間極短;
隨機 IO:磁頭需要很長的換道時間,如果隨機 IO 很多,導致磁頭不停換道,效率會大大降底
順序/並發 IO
磁盤控制器每一次對磁盤組發出的指令是一條還是多條。
順序 IO:一條指令,緩存中的 IO 隊列,只能一個一個的執行,
並發 IO:控制器同時對磁盤組中的多塊磁盤,同時發出指令,則每次可以執行多個 IO。並發 IO 模式提高了效率和速度
平均 IO 尺寸小於 32k,可認為磁盤 IO 模式以隨機為主
平均 IO 尺寸大於 32k,則以順序 IO 為主
緩存 IO
在 Linux 的緩存 I/O 機制中,數據先從磁盤復制到內核空間的緩存區,然后從內核空間緩存區復制到應用程序的用戶空間。
讀 IO:操作系統檢查內核的緩存區有沒有需要的數據,如果有,那么就直接從緩存中返回;否則從磁盤中讀取,然后再復制到操作系統的緩存中。
寫 IO:將數據從用戶空間復制到內核空間的緩存中。這時對用戶程序來說寫 IO 就已經完成。
緩存 I/O 的優點:
1)在一定程度上分離了內核空間和用戶空間,保護系統的運行安全
2)可以減少讀盤的次數,從而提高系統性能。
緩存 I/O 的缺點:
在緩存 I/O 機制中,數據直接從磁盤讀到緩存中,或者將數據從緩存直接寫回磁盤,而不能直接在用戶空間和磁盤之間進行直接的數據傳輸。數據會在傳輸過程中需要在用戶空間和內核空間之間進行多次數據拷貝操作,每一次數據拷貝都需要內核和用戶空間進行上下文切換,而頻繁的上下文切換則會導致 cpu 和內存資源的大量消耗。
直接 IO
直接 IO 就是應用程序直接訪問磁盤數據,不經過內核緩存區,這樣做的目的是減少從內核緩存區到用戶空間的數據拷貝次數。比如數據庫這類應用更傾向於選擇自身的緩存機制,因為數據庫管理系統比操作系統更了解自身存放的數據。它可以提供一種更加有效的緩存機制來提高數據的存取性能。
同步/異步 IO
磁盤發出指令:把數據寫入到內存中,寫完之后再發出通知。這種操作叫做直接內存訪問(Direct memory access),整個過程不需要 CPU 參與。這個過程中 CPU 有兩個選擇:等待或者去繼續做其他事。前者就是同步 IO,后者就是異步 IO。
通常直接 IO 與異步 IO 組合使用,會極大提高系統性能
IO 瓶頸分析
vmstat 命令
其中關於 IO 的幾個指標解釋如下:
bi:讀磁盤的速度,單位 KB/秒
bo:寫磁盤的速度
wa:IO 的時間
瓶頸分析:
1:wa 並不能反應磁盤的瓶頸,實際反應的是 cpu 的 io 等待時間
2:bi+bo 參考值為 1000,如果超過 1000,而且 wa 值比較大,表示系統磁盤 IO 存在瓶頸
iostat 命令
rrqm/s: 每秒對該設備的讀請求被合並次數,文件系統會對讀取同塊 (block) 的請求進行合並
wrqm/s: 每秒對該設備的寫請求被合並次數
r/s: 每秒完成的讀次數
w/s: 每秒完成的寫次數
rkB/s: 每秒讀數據量 (kB 為單位)
wkB/s: 每秒寫數據量 (kB 為單位)
avgrq-sz:平均每次 IO 操作的數據量 (扇區數為單位)
avgqu-sz: 是平均請求隊列的長度。隊列長度越短越好
await: 平均每次 IO 請求等待時間 (包括等待時間和處理時間,毫秒為單位)。一般地系統 IO 響應時間應該低於 5ms
svctm: 平均每次 IO 請求的處理時間 (毫秒為單位)
%util: 1 秒中有百分之多少的時間用於 I/O 操作。該參數表示了設備的繁忙程度
瓶頸分析:
1:CPU 會拿出一部分時間來等待 IO(iowait)。如果磁盤的利用率已經滿了(util%),即使 CPU 使用率不高,但是系統整體 QPS 已經上不去了,如果繼續加大流量,會導致單次 iowait 持續增加(IO 請求都堵在隊列里),從而使整體性能塌方。
2:高 iowait 並不代表磁盤的瓶頸。唯一能說明磁盤是系統瓶頸的方法是很高的 svctm(IO 請求的處理時間),一般來說超過 20ms,就代表了不太正常的磁盤性能。只要大於 20ms,就必須考慮是否磁盤讀寫的次數太多,導致磁盤性能降低。
3:svctm 一般要小於 await。svctm 的大小和磁盤性能有關,請求過多也會導致 svctm 的增加。await 的大小一般取決於 svctm 以及 I/O 隊列的長度。如果 svctm 接近 await,說明 I/O 幾乎沒有等待時間;如果 await 遠大於 svctm,說明 I/O 隊列太長,應用的響應時間變慢,如果響應時間超過了用戶可以容許的范圍,需要考慮更換更快的磁盤;調整內核 elevator 算法;優化應用;升級 CPU
舉例形容 IO
超市排隊付款
1:首先看排的隊人數,5 個人比 20 人要快
2:看前面人購買的東西多少,如果前面的人購買了一個月的物品,可以考慮換個隊伍排
3:看收銀員的速度,如果碰上了新手,那等待時間會很久
與 IO 的對比:
r/s+w/s 類似於排隊的人員總數
平均隊列長度 (avgqu-sz) 相當於單位時間里平均排隊的人數
平均服務時間 (svctm) 相當於收銀員的收款速度
平均等待時間 (await) 相當於平均每人的等待時間
平均 I/O 數據 (avgrq-sz) 相當於平均每人所買的東西多少
I/O 操作率 (%util) 相當於收款台前有人排隊的時間比例
經驗總結
1:提高 IO 效率原則: 順序寫,隨機讀
2:重點監控 rkB/s 和 和 wkB/s
3:%util 接近 100%,說明產生的 I/O 請求太多,I/O 系統已經滿負荷,該磁盤可能存在瓶頸
4:await 與 svctm 相差很大的時候,要注意磁盤的 IO 性能。差值越小,說明隊列時間越短,反之則隊列時間越長。說明系統出了問題。
規避 IO 負載過高:
- 如果服務器用來做日志分析,注意隨機讀和順序寫,避免定期的壓縮、解壓大日志。
- 如果是前端應用服務器,要避免程序頻繁打本地日志、或者異常日志
- 如果是存儲服務(mysql、nosql),盡量將服務部署在單獨的節點上,做讀寫分離降低壓力
IO 調度器選擇
cat /sys/block/sda/queue/scheduler
括號中的就是默認的 IO 調度器
echo noop > /sys/block/sdb/queue/scheduler
修改調度器
來源:https://testerhome.com/articles/21493