Shell脚本如何监控磁盘IO等待

wen 实用脚本 1

本文目录导读:

Shell脚本如何监控磁盘IO等待

  1. 使用iostat监控(推荐)
  2. 使用/proc/stat监控(无需额外工具)
  3. 完整监控脚本
  4. 单行命令监控
  5. 使用说明

我来介绍几种监控磁盘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

使用说明

  1. 安装必要工具

    # CentOS/RHEL
    yum install sysstat bc
    # Ubuntu/Debian
    apt-get install sysstat bc
  2. 执行权限

    chmod +x disk_io_monitor.sh
  3. 运行监控

    # 默认监控
    ./disk_io_monitor.sh
    # 自定义阈值
    ./disk_io_monitor.sh -t 20 -c 40
    # 查看特定信息
    ./disk_io_monitor.sh --iowait
    ./disk_io_monitor.sh --disk-busy

这个脚本可以帮助你实时监控磁盘IO状态,及时发现性能问题。

抱歉,评论功能暂时关闭!