本文目录导读:

我来介绍几种监控磁盘IO等待的Shell脚本方法:
使用iostat监控(推荐)
#!/bin/bash
# 监控磁盘IO等待时间
monitor_io_wait() {
# 使用iostat监控,间隔1秒,输出1次
iostat -x 1 1 | grep -E "avg-cpu|Device" -A 1
# 或者只获取CPU等待时间
iostat -c 1 1 | grep -v "^$" | tail -n 1 | awk '{print $4}'
}
# 实时监控示例
monitor_io_continuous() {
local threshold=30 # 阈值,%iowait超过此值告警
while true; do
local iowait=$(iostat -c 1 1 | grep -v "^$" | tail -n 1 | awk '{print $4}')
echo "$(date '+%Y-%m-%d %H:%M:%S') iowait: ${iowait}%"
# 比较阈值
if (( $(echo "$iowait > $threshold" | bc -l) )); then
echo "警告: IO等待时间超过阈值 ${threshold}%"
# 可以在这里添加告警操作
fi
sleep 5
done
}
# 如果需要安装iostat
# CentOS/RHEL: yum install sysstat
# Ubuntu/Debian: apt-get install sysstat
monitor_io_continuous
使用/proc/stat监控(无需额外工具)
#!/bin/bash
get_iowait() {
# 从/proc/stat读取CPU统计信息
local cpu_stats=$(grep "^cpu " /proc/stat)
# 解析各字段
local user=$(echo $cpu_stats | awk '{print $2}')
local nice=$(echo $cpu_stats | awk '{print $3}')
local system=$(echo $cpu_stats | awk '{print $4}')
local idle=$(echo $cpu_stats | awk '{print $5}')
local iowait=$(echo $cpu_stats | awk '{print $6}')
local irq=$(echo $cpu_stats | awk '{print $7}')
local softirq=$(echo $cpu_stats | awk '{print $8}')
# 计算总CPU时间
local total=$((user + nice + system + idle + iowait + irq + softirq))
echo "iowait_cpu=$iowait total_cpu=$total"
# 返回iowait百分比
if [ $total -gt 0 ]; then
echo "scale=2; $iowait * 100 / $total" | bc
else
echo "0"
fi
}
# 计算iowait百分比变化
calculate_iowait_percent() {
local sample1=($(get_iowait | grep -oP '\d+'))
sleep 1
local sample2=($(get_iowait | grep -oP '\d+'))
local iowait_diff=$((sample2[0] - sample1[0]))
local total_diff=$((sample2[1] - sample1[1]))
if [ $total_diff -gt 0 ]; then
echo "scale=2; $iowait_diff * 100 / $total_diff" | bc
else
echo "0"
fi
}
# 连续监控
while true; do
local iowait=$(calculate_iowait_percent)
echo "$(date '+%Y-%m-%d %H:%M:%S') %iowait: ${iowait}%"
sleep 2
done
完整监控脚本
#!/bin/bash
# 磁盘IO监控脚本
# 使用方法: ./disk_io_monitor.sh [选项]
# 配置
THRESHOLD_WARN=30 # 警告阈值(%)
THRESHOLD_CRIT=50 # 严重阈值(%)
SLEEP_INTERVAL=5 # 检查间隔(秒)
LOG_FILE="/var/log/disk_io_monitor.log"
# 日志函数
log() {
local level=$1
local message=$2
local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
echo "[${timestamp}] [${level}] ${message}" | tee -a $LOG_FILE
}
# 获取磁盘IO等待时间
get_iowait() {
if command -v iostat &> /dev/null; then
# 使用iostat
iostat -c 1 1 | grep -v "^$" | tail -n 1 | awk '{print $4}'
else
# 使用/proc/stat
local sample1=$(grep "^cpu " /proc/stat)
sleep 1
local sample2=$(grep "^cpu " /proc/stat)
local iowait1=$(echo $sample1 | awk '{print $6}')
local total1=$(echo $sample1 | awk '{print $2+$3+$4+$5+$6+$7+$8}')
local iowait2=$(echo $sample2 | awk '{print $6}')
local total2=$(echo $sample2 | awk '{print $2+$3+$4+$5+$6+$7+$8}')
local iowait_diff=$((iowait2 - iowait1))
local total_diff=$((total2 - total1))
if [ $total_diff -gt 0 ]; then
echo "scale=2; $iowait_diff * 100 / $total_diff" | bc
else
echo "0"
fi
fi
}
# 获取磁盘繁忙度
get_disk_busy() {
if command -v iostat &> /dev/null; then
# 显示磁盘使用率最高的设备
iostat -x 1 1 | grep -E "^[s,h,v]d[a-z]" | sort -k14 -rn | head -5 | \
awk '{printf "%-10s %-10s %-10s %-10s\n", $1, $14"%", $12, $13}'
fi
}
# 获取IOPS信息
get_iops() {
if command -v iostat &> /dev/null; then
echo "磁盘IOPS信息:"
iostat -x 1 1 | grep -E "^[s,h,v]d[a-z]" | \
awk '{printf "%-10s r/s:%-10s w/s:%-10s rkB/s:%-10s wkB/s:%-10s\n", $1, $2, $3, $6, $7}'
fi
}
# 主要监控逻辑
monitor_main() {
log "INFO" "开始磁盘IO监控..."
log "INFO" "警告阈值: ${THRESHOLD_WARN}%, 严重阈值: ${THRESHOLD_CRIT}%"
while true; do
local iowait=$(get_iowait)
local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
# 比较阈值
if (( $(echo "$iowait > $THRESHOLD_CRIT" | bc -l) )); then
log "CRITICAL" "严重: IO等待时间 ${iowait}% (阈值: ${THRESHOLD_CRIT}%)"
log "CRITICAL" "$(get_disk_busy)"
log "CRITICAL" "$(get_iops)"
# 发送邮件告警(可选)
# echo "IO等待时间严重: ${iowait}%" | mail -s "IO告警" admin@example.com
elif (( $(echo "$iowait > $THRESHOLD_WARN" | bc -l) )); then
log "WARNING" "警告: IO等待时间 ${iowait}% (阈值: ${THRESHOLD_WARN}%)"
else
log "INFO" "正常: IO等待时间 ${iowait}%"
fi
sleep $SLEEP_INTERVAL
done
}
# 显示帮助信息
show_help() {
echo "磁盘IO监控脚本"
echo "用法: $0 [选项]"
echo "选项:"
echo " -h, --help 显示帮助信息"
echo " -t, --threshold 设置警告阈值 (默认: 30)"
echo " -c, --critical 设置严重阈值 (默认: 50)"
echo " -i, --interval 设置检查间隔秒数 (默认: 5)"
echo " -l, --log 设置日志文件路径"
echo " --iowait 只显示IO等待时间"
echo " --disk-busy 显示磁盘繁忙度"
echo " --iops 显示IOPS信息"
}
# 参数解析
case "${1:-}" in
-h|--help)
show_help
exit 0
;;
--iowait)
watch -n 1 "echo 'IO等待时间:' && iostat -c 1 1 | tail -n 2 | head -n 1 | awk '{print \"%iowait: \"\$4}'"
;;
--disk-busy)
watch -n 1 "echo '磁盘繁忙度(利用率排名前5):' && iostat -x 1 1 | grep -E '^[s,h,v]d[a-z]' | sort -k14 -rn | head -5 | awk '{printf \"%-10s %-10s\n\", \$1, \$14\"%\"}'"
;;
--iops)
watch -n 1 "echo '磁盘IOPS:' && iostat -x 1 1 | grep -E '^[s,h,v]d[a-z]' | awk '{printf \"%-10s r/s:%-10s w/s:%-10s\n\", \$1, \$2, \$3}'"
;;
*)
monitor_main
;;
esac
单行命令监控
# 持续监控IO等待时间
watch -n 1 "iostat -c 1 1 | tail -n 2 | head -n 1 | awk '{print \"%iowait: \"\$4}'"
# 监控IO等待并记录到文件
while true; do echo "$(date '+%Y-%m-%d %H:%M:%S') $(iostat -c 1 1 | tail -n 2 | head -n 1 | awk '{print $4}')"; sleep 5; done >> iowait.log
# 监控特定磁盘
iostat -x sda 1 1
# 查看IO等待进程
iotop -oP
使用说明
-
安装必要工具:
# CentOS/RHEL yum install sysstat bc # Ubuntu/Debian apt-get install sysstat bc
-
执行权限:
chmod +x disk_io_monitor.sh
-
运行监控:
# 默认监控 ./disk_io_monitor.sh # 自定义阈值 ./disk_io_monitor.sh -t 20 -c 40 # 查看特定信息 ./disk_io_monitor.sh --iowait ./disk_io_monitor.sh --disk-busy
这个脚本可以帮助你实时监控磁盘IO状态,及时发现性能问题。