| 指標 | 含義 | 異常閾值參考 |
| IOPS (tps) | 每秒 I/O 次數 (讀+寫) | 視磁碟類型:SATA ~100-150, SAS ~200-300, SSD 萬級 |
| 吞吐量 | 每秒讀寫總資料量 (KB/s, MB/s) | 接近磁碟頂規值 |
| 平均 I/O 大小 | 吞吐量 / IOPS | < 32KB 隨機為主, > 32KB 循序為主 |
| 利用率 (%util) | 磁碟忙碌時間百分比 | > 70% 持續視為瓶頸 |
| 服務時間 (svctm) | 單次 I/O 完成時間 (ms) | > 20ms 持續影響應用 |
| 隊列長度 (avgqu-sz) | 待處理 I/O 請求數 | 單盤 > 2 持續視為瓶頸 (RAID 需除以物理盤數) |
| 等待時間 (await) | 隊列等待 + 服務時間 (ms) | 遠大於 svctm 表示嚴重排隊 |
優化手段清單
- 調整資料佈局,均衡 I/O 到各物理磁碟。
- RAID 條帶大小對齊應用 I/O (或為倍數),選擇 RAID10/RAID5。
- 調大驅動佇列深度 (不超過硬體處理能力)。
- 應用層/檔案系統層快取減少磁碟存取。
- 資料庫繞過檔案系統快取 (Raw partition / O_DIRECT)。
- 熱點資料放入記憶體 (tmpfs / Redis / 應用級快取)。
iostat / sar 輸出對照 (AIX vs Linux)
AIX: iostat -d
% tm_act Kbps tps Kb_read Kb_wrtn
hdisk3 94.2 40013 73.3 9795 390643
% tm_act = 利用率
Kbps = 吞吐量
tps = IOPS
AIX: sar -d
%busy avque r+w/s Kbs/s avwait avserv
hdisk3 92 0.1 72 38773 28.5 105.1
%busy = 利用率
avque = 平均隊列長度
avserv = 服務時間 (ms)
avwait = 等待時間 (ms)
Linux: iostat -d -x
r/s w/s rsec/s wsec/s avgrq-sz avgqu-sz await svctm %util
0.14 2.06 12.98 286.60 136.58 0.19 87.17 3.76 0.82
r/s, w/s:每秒讀/寫次數
rsec/s, wsec/s:每秒讀/寫扇區數 (扇區=512B)
avgrq-sz:平均請求扇區數
avgqu-sz:平均隊列長度
await:平均等待時間 (ms)
svctm:平均服務時間 (ms)
%util:利用率
Linux: sar -d
tps rd_sec/s wr_sec/s avgrq-sz avgqu-sz await svctm %util
266 0 3102 11.66 1.47 5.52 3.72 99.08
自動化監控告警腳本 IOAnalyzer.sh 設計精華
架構
- 輸入:
iostat -d [-x] interval count > iostat.out 後台持續寫入。
- 分析器:
IOAnalyzer.sh -i iostat.out -u 80 -r 70 定時 (crontab 10 分鐘) 掃描新增行。
- 判斷邏輯:某磁碟利用率 ≥
-u (預設 80%) 的樣本佔比 ≥ -r (預設 70%) → 觸發告警。
- 輸出:日誌
.log 記錄分析範圍/結果,告警 .alert 郵件發送 root。
- 跨平台:自動偵測
uname,AIX 取 % tm_act (第 2 欄),Linux 取 %util (第 14 欄)。
關鍵代碼片段
# 定位新增行 (避免重複分析)
if [ ! -f "$log" ] || ! tail -1 "$log" | grep -q ENDLINE; then
start=1
else
start=$(($(tail -1 "$log" | awk '{print $4}' | cut -d: -f2) + 1))
fi
sed -n "${start},\$p" "$iostat_file" > tail_part
# 逐行判斷
awk -v col=$util_col -v thresh=$diskUtil '
$col*100 < thresh {print $1 "\t" $col "\tOK"}
$col*100 >= thresh {print $1 "\t" $col "\tAlarm"}
' tail_part > result.tmp
# 統計告警率
for disk in $(cut -f1 result.tmp | sort -u); do
alarm=$(grep "^$disk.*Alarm$" result.tmp | wc -l)
total=$(grep "^$disk" result.tmp | wc -l)
rate=$((alarm * 100 / total))
if [ $rate -ge $rateGEUtil ]; then
echo "DISK:$disk TIME:$(date +%Y%m%d%H%M) RATE:$rate THRESHOLD:$rateGEUtil" >> alert.tmp
fi
done
部署範例
# 1. 後台持續收集
nohup iostat -d -x 5 > /root/iostat.out &
# 2. crontab 每 10 分鐘分析
0,10,20,30,40,50 * * * * /root/IOAnalyzer.sh -i /root/iostat.out -u 70 -r 80 >/tmp/ia.log 2>&1
總結
iostat/sar 是 Unix/Linux 磁碟 I/O 可視化的雙核利器。結合指標閾值、自動化腳本 (持久化採集 + 增量分析 + 告警率判斷 + 郵件通知),可將「事後發現」轉為「事前預警」,配合資料佈局調整、快取策略、RAID 調優,構建完整 I/O 效能管理閉環。