本文目录导读:

我来介绍几种监控磁盘IO读写状态的脚本方法:
使用 iostat 命令
基础监控脚本
#!/bin/bash # 磁盘IO监控脚本 - iostat方式 # 安装sysstat包(如果未安装) # apt-get install sysstat # Debian/Ubuntu # yum install sysstat # CentOS/RHEL # 监控磁盘IO(每2秒刷新) iostat -x 2 # 查看特定磁盘 iostat -x sda 2 # 监控并输出到文件 iostat -x -t 1 > /var/log/disk_io.log &
高级监控脚本
#!/bin/bash
# 配置
DISK="sda" # 要监控的磁盘
INTERVAL=1 # 采样间隔(秒)
THRESHOLD_READ=100 # 读IOPS阈值
THRESHOLD_WRITE=100 # 写IOPS阈值
THRESHOLD_UTIL=80 # 磁盘使用率阈值(%)
monitor_disk_io() {
while true; do
# 获取IO统计数据
IO_INFO=$(iostat -x $DISK 1 2 | tail -1)
# 提取关键指标
R_IOPS=$(echo $IO_INFO | awk '{print $4}')
W_IOPS=$(echo $IO_INFO | awk '{print $5}')
R_MB=$(echo $IO_INFO | awk '{print $6}')
W_MB=$(echo $IO_INFO | awk '{print $7}')
UTIL=$(echo $IO_INFO | awk '{print $12}')
# 检查阈值并告警
if (( $(echo "$UTIL > $THRESHOLD_UTIL" | bc -l) )); then
echo "[ALERT] 磁盘 $DISK 使用率过高: ${UTIL}%"
fi
# 记录日志
echo "$(date '+%Y-%m-%d %H:%M:%S'),${R_IOPS},${W_IOPS},${UTIL}%" >> /var/log/disk_io.log
sleep $INTERVAL
done
}
monitor_disk_io
使用 iotop 命令
#!/bin/bash
# 使用iotop监控进程级别的IO
# 安装iotop
# apt-get install iotop
# 实时监控
iotop -oP # 只显示有IO活动的进程
# 批量模式输出
iotop -b -n 3 -oP > /tmp/iotop_output.txt
# 脚本方式
monitor_process_io() {
iotop -b -n 1 -oP | while read line; do
PID=$(echo $line | awk '{print $1}')
DISK_READ=$(echo $line | awk '{print $4}')
DISK_WRITE=$(echo $line | awk '{print $6}')
echo "PID: $PID, Read: $DISK_READ, Write: $DISK_WRITE"
done
}
使用 /proc/diskstats
#!/bin/bash
# 直接从/proc文件系统读取IO数据
# 磁盘设备列表
DISKS=("sda" "sdb" "nvme0n1")
monitor_disk_stats() {
local disk=$1
# 读取初始值
local init=$(awk "/${disk} /" /proc/diskstats | awk '{print $6, $10}')
local init_read=$(echo $init | awk '{print $1}')
local init_write=$(echo $init | awk '{print $2}')
sleep 1
# 读取1秒后的值
local final=$(awk "/${disk} /" /proc/diskstats | awk '{print $6, $10}')
local final_read=$(echo $final | awk '{print $1}')
local final_write=$(echo $final | awk '{print $2}')
# 计算IOPS
local read_iops=$((final_read - init_read))
local write_iops=$((final_write - init_write))
echo "$disk: Read ${read_iops} ops/s, Write ${write_iops} ops/s"
}
# 主循环
while true; do
for disk in "${DISKS[@]}"; do
monitor_disk_stats $disk
done
sleep 1
done
综合监控脚本
#!/usr/bin/env python3
"""
磁盘IO监控脚本 - Python版本
"""
import subprocess
import time
import json
from datetime import datetime
class DiskMonitor:
def __init__(self, disk_name="sda"):
self.disk = disk_name
def get_io_stats(self):
"""获取磁盘IO统计"""
result = subprocess.run(
['iostat', '-x', self.disk, '1', '1'],
capture_output=True,
text=True
)
lines = result.stdout.strip().split('\n')
# 解析iostat输出
for line in lines:
if self.disk in line:
stats = line.split()
return {
'timestamp': datetime.now().isoformat(),
'disk': self.disk,
'r/s': float(stats[3]),
'w/s': float(stats[4]),
'rkB/s': float(stats[5]),
'wkB/s': float(stats[6]),
'avgqu-sz': float(stats[8]),
'await': float(stats[9]),
'svctm': float(stats[10]),
'util': float(stats[11])
}
return None
def monitor(self, interval=1, threshold_util=80):
"""持续监控"""
while True:
stats = self.get_io_stats()
if stats:
# 检查阈值
if stats['util'] > threshold_util:
print(f"[ALERT] 磁盘 {self.disk} 使用率: {stats['util']}%")
# 输出JSON格式
print(json.dumps(stats))
# 记录到文件
with open('/var/log/disk_io_monitor.log', 'a') as f:
f.write(json.dumps(stats) + '\n')
time.sleep(interval)
# 使用示例
if __name__ == "__main__":
monitor = DiskMonitor("sda")
monitor.monitor(interval=2)
告警通知脚本
#!/bin/bash
# 带告警通知的IO监控
# 配置
DISK="sda"
THRESHOLD_IO_UTIL=90
THRESHOLD_IOPS=1000
INTERVAL=5
LOG_FILE="/var/log/disk_io_alerts.log"
EMAIL="admin@example.com"
# 告警函数
send_alert() {
local message="$1"
echo "$(date): $message" >> $LOG_FILE
# 邮件告警
echo "$message" | mail -s "[IO Alert] $HOSTNAME" $EMAIL
# 发送到Slack (可选)
# curl -X POST -H 'Content-type: application/json' \
# --data "{\"text\":\"$message\"}" \
# YOUR_SLACK_WEBHOOK_URL
}
# 主监控逻辑
while true; do
# 获取IO数据
IO_DATA=$(iostat -x $DISK 1 2 | tail -1)
# 提取指标
R_IOPS=$(echo $IO_DATA | awk '{print $4}')
W_IOPS=$(echo $IO_DATA | awk '{print $5}')
IO_UTIL=$(echo $IO_DATA | awk '{print $12}')
# 检查告警条件
if (( $(echo "$IO_UTIL > $THRESHOLD_IO_UTIL" | bc -l) )); then
send_alert "磁盘 $DISK IO使用率过高: ${IO_UTIL}%"
fi
if (( $(echo "$R_IOPS + $W_IOPS > $THRESHOLD_IOPS" | bc -l) )); then
send_alert "磁盘 $DISK IOPS过高: 读${R_IOPS} 写${W_IOPS}"
fi
sleep $INTERVAL
done
使用 dstat 命令
#!/bin/bash # dstat方式监控 # 安装dstat # apt-get install dstat # 显示磁盘IO dstat -d # 显示详细磁盘信息 dstat -D sda -d 1 10 # 脚本使用 dstat -d --output /tmp/disk_io.csv 1 3600
Grafana + Prometheus 方案
如果需要长期监控和可视化,建议使用:
# node_exporter 配置
- job_name: 'node'
static_configs:
- targets: ['localhost:9100']
# Prometheus 查询
# node_disk_io_time_seconds_total{device="sda"}
# rate(node_disk_io_time_seconds_total{device="sda"}[1m])
监控要点
-
关键指标:
- IOPS(每秒IO操作数)
- 吞吐量(读写速率)
- 等待时间(await)
- 队列长度
- 磁盘使用率
-
告警阈值:
- 磁盘使用率 > 80% 告警
- 等待时间 > 100ms 告警
- IOPS > 磁盘规格的80%
-
优化建议:
- 使用SSD替代HDD提升IOPS
- RAID配置提高读写性能
- 调整内核IO调度器
选择最适合你场景的脚本,建议结合多个工具进行综合监控。