用iostat配合脚本监控核心磁盘需串联实时采集、阈值判断与结果留存三步,明确指定物理设备名(如nvme0n1),避免使用ALL或LVM逻辑卷,并通过lsblk和/sys/block确认设备类型与型号。

用 iostat 配合脚本监控核心磁盘,关键是把实时指标采集、关键阈值判断和结果留存三步串起来,而不是只跑一条命令。
明确要监控的核心设备
先确认目标磁盘名,比如 sda(传统 SATA)、nvme0n1(NVMe SSD)或 md0(软 RAID)。避免用模糊名称如 ALL 或未映射的 LVM 逻辑卷(如 /dev/mapper/vg-root),iostat 默认不识别这些。可执行:
-
lsblk -d -o NAME,ROTA,MODEL查看物理设备及是否为旋转盘(ROTA=1 是机械盘) -
cat /sys/block/nvme0n1/device/model 2>/dev/null确认 NVMe 型号
写一个轻量可靠的监控脚本
以下是一个专注核心磁盘、带基础告警逻辑的 Bash 脚本示例(保存为 disk-watch.sh):
#!/bin/bash
DEVICE="nvme0n1" # 替换为你的真实设备名
THRESHOLD_AWAIT=5 # SSD 告警阈值(ms),机械盘建议设为 20
THRESHOLD_UTIL=90 # %util 告警阈值(仅作参考,非决定性)
LOG_FILE="/var/log/disk_io_alert.log"
<h1>每 3 秒采样一次,取最近 2 次稳定值(跳过首行抖动)</h1><p>OUTPUT=$(iostat -dx $DEVICE 3 2 | tail -n 1)</p><p>if [[ -z "$OUTPUT" ]]; then
echo "$(date): iostat failed or device $DEVICE not found" >> "$LOG_FILE"
exit 1
fi</p><h1>提取关键字段(按空格分割,位置固定)</h1><p>AWAIT=$(echo "$OUTPUT" | awk '{print $10}')
UTIL=$(echo "$OUTPUT" | awk '{print $14}')</p><h1>判断并记录异常</h1><p>if (( $(echo "$AWAIT > $THRESHOLD_AWAIT" | bc -l) )); then
echo "$(date): [ALERT] $DEVICE await=$AWAIT ms (> $THRESHOLD_AWAIT) — possible I/O latency" >> "$LOG_FILE"
fi</p><p>if (( $(echo "$UTIL > $THRESHOLD_UTIL" | bc -l) )); then
echo "$(date): [WARN] $DEVICE %util=$UTIL% — device busy, check throughput vs. capacity" >> "$LOG_FILE"
fi
说明:
– 使用 -dx 获取扩展指标,3 2 表示每 3 秒刷新、共 2 次输出,tail -n 1 取第二次(更稳)
– 重点依赖 await(真实延迟),而非仅看 %util(对 NVMe 已弱化)
– 用 bc 支持浮点比较,避免整数截断误差
让脚本持续运行并可控管理
不要用 & 简单后台跑,推荐两种方式:
-
systemd 服务(推荐):新建
/etc/systemd/system/disk-watch.service,启用后自动开机运行、崩溃重启、日志归集到 journal -
crontab 定时触发:例如每分钟执行一次:
*/1 * * * * /path/to/disk-watch.sh,适合轻量或测试环境
无论哪种方式,都应设置日志轮转(如用 logrotate)防止日志撑爆磁盘。
配合其他工具交叉验证
iostat 单独不能定位进程级 I/O 源。发现异常后快速跟进:
- 查谁在读写:
iotop -oP(只显示实际 I/O 的进程) - 查文件级热点:
sudo lsof +D /data | awk '$5~/REG/ {print $1,$9}' | sort | uniq -c | sort -nr | head -5 - 查内核队列深度:
cat /sys/block/$DEVICE/queue/nr_requests(默认 128,若 avgqu-sz 长期 >100,说明请求积压严重)
不复杂但容易忽略


















