Linux 磁盘 IO 性能问题排查指南
一、问题现象
磁盘 IO 问题通常表现为:
- 系统响应缓慢,尤其是文件操作
- 应用程序读写超时
top命令中%wa(io wait) 持续偏高
- 日志中出现 I/O timeout 错误
- 数据库查询变慢或卡住
二、快速诊断命令
2.1 查看整体 IO 状态
1 2 3 4 5 6 7 8
| top
iostat -x 1
iotop -oPa
|
2.2 关键指标解读
| 指标 |
含义 |
正常值 |
| %util |
磁盘利用率 |
< 80% |
| await |
平均等待时间 (ms) |
< 10ms |
| svctm |
平均服务时间 (ms) |
< 5ms |
| %wa |
CPU IO 等待 |
< 20% |
三、定位问题进程
3.1 使用 iotop 找出 IO 大户
1 2 3 4 5
| iotop -oPa
iotop -oPaP $(pgrep mysql)
|
3.2 使用 pidstat 监控进程 IO
1 2 3 4 5
| pidstat -d 1
pidstat -d -p <PID> 1
|
3.3 查看进程打开的文件
1 2 3 4 5
| lsof -p <PID>
cat /proc/<PID>/io
|
四、磁盘性能测试
4.1 使用 dd 测试顺序读写
1 2 3 4 5 6
| dd if=/dev/zero of=/tmp/testfile bs=1M count=1024 conv=fdatasync
echo 3 > /proc/sys/vm/drop_caches dd if=/tmp/testfile of=/dev/null bs=1M
|
4.2 使用 fio 进行综合测试
1 2 3 4 5 6 7 8 9 10 11 12 13
| apt install fio yum install fio
fio --name=randread --ioengine=libaio --iodepth=1 \ --rw=randread --bs=4k --direct=1 --size=1G \ --numjobs=4 --runtime=60 --group_reporting
fio --name=randwrite --ioengine=libaio --iodepth=1 \ --rw=randwrite --bs=4k --direct=1 --size=1G \ --numjobs=4 --runtime=60 --group_reporting
|
五、常见问题与解决方案
5.1 磁盘利用率过高
现象: %util 接近 100%
排查:
1 2 3 4 5 6
| iostat -x 1
df -h mount | grep <device>
|
解决:
- 迁移高 IO 负载到其他磁盘
- 增加磁盘缓存(调整 vm.dirty_ratio)
- 优化应用程序 IO 模式
5.2 大量小文件读写
现象: IOPS 高但吞吐量低
解决:
- 合并小文件操作
- 使用异步 IO
- 考虑使用 SSD 或 NVMe
- 调整文件系统参数(noatime)
5.3 磁盘队列过长
现象: avgqu-sz 持续大于 1
排查:
1 2
| iostat -x 1 | grep -A1 Device
|
解决:
- 降低并发 IO 请求
- 增加磁盘数量(RAID/LVM)
- 升级更快存储设备
5.4 交换分区频繁使用
现象: 磁盘 IO 高且 swap 使用率高
排查:
解决:
- 增加物理内存
- 调整 swappiness:
sysctl vm.swappiness=10
- 优化应用程序内存使用
六、优化建议
6.1 文件系统挂载参数
1 2
| /dev/sda1 /data ext4 noatime,nodiratime,commit=60 0 2
|
| 参数 |
作用 |
| noatime |
不更新访问时间 |
| nodiratime |
不更新目录访问时间 |
| commit=60 |
60 秒提交一次(默认 5 秒) |
6.2 内核参数调优
1 2 3 4 5 6 7 8 9 10
|
vm.dirty_ratio = 20 vm.dirty_background_ratio = 10
vm.swappiness = 10
vm.read_ahead_kb = 4096
|
6.3 应用层优化
- 使用连接池减少数据库 IO
- 批量写入代替频繁小写入
- 使用缓存层(Redis/Memcached)
- 异步处理非关键 IO 操作
七、监控告警配置
7.1 Prometheus 监控指标
1 2 3 4 5 6 7 8 9
| node_disk_io_time_seconds_total
node_disk_read_bytes_total node_disk_written_bytes_total
node_disk_io_time_weighted_seconds_total
|
7.2 告警规则示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| groups: - name: disk_io rules: - alert: DiskIOLatencyHigh expr: rate(node_disk_io_time_weighted_seconds_total[5m]) / rate(node_disk_io_time_seconds_total[5m]) > 0.8 for: 5m labels: severity: warning annotations: summary: "磁盘 IO 延迟过高" - alert: DiskUtilizationHigh expr: rate(node_disk_io_time_seconds_total[1m]) > 0.9 for: 10m labels: severity: critical annotations: summary: "磁盘利用率持续高于 90%"
|
八、排查流程图
1 2 3 4 5 6 7 8 9 10 11 12 13
| 发现 IO 问题 ↓ top 查看%wa 是否高? ↓是 iostat -x 1 定位磁盘 ↓ iotop 找出问题进程 ↓ 分析进程行为 ↓ ├─ 正常业务高峰 → 考虑扩容/优化 ├─ 异常进程 → 终止/限制 └─ 配置问题 → 调整参数
|
九、总结
磁盘 IO 问题排查核心步骤:
- 确认现象:通过 top/iostat 确认 IO 是瓶颈
- 定位磁盘:找出 IO 最高的设备
- 定位进程:用 iotop 找出 IO 大户
- 分析原因:是正常负载还是异常行为
- 采取措施:优化配置/限制进程/扩容硬件
记住:IO 问题往往是表象,根本原因可能是内存不足、应用设计缺陷或硬件老化。