Linux

服务器磁盘 IO 异常全场景总结

·10 分钟阅读·3755 字
📋 目录

服务器磁盘 IO 异常全场景总结

核心概念 磁盘 IO 异常通过 iostat/iotop/vmstat 等工具定位,覆盖 util 100%、iowait 高、IOPS 打满等典型场景。

1. 前置基础指标

核心观测命令:iostat、iotop、vmstat、sar -d
关键指标:

  • %iowait:CPU等待磁盘IO的时间占比(大于30%判定IO压力大)
  • %util:磁盘设备繁忙度,接近100%代表磁盘打满瓶颈
  • rMB/s、wMB/s 读写带宽;r/s、w/s 每秒读写IO次数(IOPS)
  • avgqu-sz:IO请求平均队列长度,数值越大阻塞越严重
  • await:单次IO平均等待耗时,正常<10ms,几十上百ms代表磁盘拥堵

2. 场景1:磁盘util持续100%,iowait高,业务大量超时阻塞

2.1. 现象

  1. iostat -x 1 磁盘%util=100%%iowait长期40%~90%;
  2. 业务接口缓慢、数据库查询超时、日志输出卡顿;
  3. shell命令、ls、cat文件执行延迟;
  4. 系统load average持续走高,但CPU idle空闲很多;
  5. Java应用频繁STW、大量线程阻塞在写文件。

2.2. 根因

  1. 高频随机读写(数据库MySQL/Redis、ES分片、Kafka),IOPS打满磁盘上限;
  2. 大量同步刷盘策略:MySQL sync_binlog=1、Redis AOF always、频繁flush;
  3. 海量日志同步落盘,应用疯狂打error堆栈日志;
  4. 定时任务扎堆:日志切割、数据库统计、全量备份、ES段合并;
  5. 机械硬盘HDD,随机读写性能极差,并发下极易跑满util。

2.3. 排查方案

  1. 定位占用IO最高进程
iotop -oP # 只展示有IO操作的进程,按读写排序
pidstat -d 1 # 按进程输出磁盘读写速度
  1. 查看磁盘读写指标,区分读瓶颈/写瓶颈
iostat -x 1
# r/s高=读瓶颈;w/s高=写瓶颈
  1. 定位进程读写哪些文件
lsof -p PID # 查看进程打开的文件句柄
cat /proc/PID/io # 进程累计读写字节
  1. 确认定时任务、中间件后台任务日志
grep -E "merge|backup|dump" /var/log/messages
crontab -l

2.4. 解决方案

  1. 硬件升级:HDD更换SSD/NVMe,大幅提升随机IOPS;
  2. 调整刷盘策略,减少同步落盘:
  • MySQL:sync_binlog=1000,innodb_flush_log_at_trx_commit=2;
  • Redis:AOF appendfsync everysec;
  1. 日志优化:关闭冗余堆栈日志,日志输出异步缓冲,日志落盘单独磁盘;
  2. 拆分定时任务,错峰执行,禁止凌晨同时备份+统计;
  3. 数据库分库分表、冷热数据分离,冷数据归档至低速存储。

3. 场景2:大量写IO,磁盘wMB/s、w/s极高,读压力很小

3.1. 现象

  1. w/s、wMB/s 数值暴涨,r/s 很低,util接近100%;
  2. 磁盘await持续升高,写入请求排队;
  3. 写入业务阻塞,读取业务基本不受影响。

3.2. 根因

  1. 消息队列Kafka/RocketMQ大量消息落地;
  2. 应用疯狂输出业务日志、异常堆栈;
  3. 数据库大批量insert、批量导入数据;
  4. 定时全量备份、数据reindex、文件同步rsync;
  5. 系统脏页积压,内核集中刷脏页产生写风暴。

3.3. 排查方案

  1. iotop 定位写IO大户;
  2. 查看内核脏页占用:cat /proc/meminfo | grep Dirty
  3. 查看应用日志输出速率、中间件日志磁盘占用增速。

3.4. 解决方案

  1. 日志分离:日志单独挂载高速磁盘,业务盘与日志盘物理隔离;
  2. 调整内核脏页参数,平缓刷盘,避免瞬间写风暴:
vm.dirty_background_ratio = 5
vm.dirty_ratio = 10
  1. 批量写入拆分批次,降低单次写入并发;
  2. Kafka调整log.flush策略,减少高频同步刷盘;
  3. 备份任务限流、错峰执行,避开业务高峰。

4. 场景3:大量读IO,r/s、rMB/s拉满,写入正常

4.1. 现象

磁盘读IO打满,查询类业务缓慢,写入无明显延迟。

4.2. 根因

  1. 数据库无索引全表扫描、频繁大分页查询;
  2. ES高基数聚合、海量日志检索;
  3. 定时报表全量读取历史数据;
  4. 程序频繁加载大文件、本地缓存失效反复读盘;
  5. 内存不足,大量文件无法缓存,频繁缺页中断读磁盘。

4.3. 排查方案

  1. pidstat -d 1 定位读IO进程;
  2. 查看数据库慢查询日志,定位全表扫描SQL;
  3. free -h 查看可用内存、Cache占用。

4.4. 解决方案

  1. 数据库加索引,优化慢SQL,限制全表查询;
  2. 增加应用内存缓存(Redis本地缓存),热点数据常驻内存;
  3. ES冷热分离,冷数据冻结/归档,热数据放高速SSD;
  4. 增大服务器内存,提升PageCache缓存命中率。

5. 场景4:iowait高,但磁盘util不高,IO队列长

5.1. 现象

util 60%~80%,avgqu-sz 队列很长,await几十ms,单IO耗时久。

5.2. 根因

  1. 机械硬盘寻道慢,随机IO延迟高;
  2. 磁盘存在坏道,读写重试耗时;
  3. 存储远端NAS/云存储网络延迟高,远程IO往返耗时;
  4. 单磁盘多业务混跑,读写争抢资源。

5.3. 排查方案

  1. 磁盘健康检测:smartctl -a /dev/sda 查看坏块、重映射扇区;
  2. 区分本地盘/远程NAS存储;
  3. iostat观察单块磁盘多业务读写并发。

5.4. 解决方案

  1. 更换SSD本地盘替代HDD/NAS;
  2. 磁盘故障则下线更换硬盘,数据迁移;
  3. 业务物理分盘,数据库、日志、程序分开挂载不同磁盘。

6. 场景5:脏页风暴,周期性瞬时IO尖峰

6.1. 现象

平时IO平稳,每隔一段时间瞬间util打满,业务短暂卡顿,周期性毛刺。

6.2. 根因

  1. 内核脏页达到阈值,后台一次性批量刷脏页;
  2. Redis RDB持久化、MySQL定时落盘、定时日志切割压缩;
  3. ES定时段合并、定时数据统计任务。

6.3. 排查方案

  1. 监控磁盘IO时序曲线,确认尖峰固定周期;
  2. 查看定时任务、中间件持久化日志;
  3. 监控 /proc/meminfo Dirty脏页数值变化。

6.4. 解决方案

  1. 调小脏页后台比例,持续平缓刷盘,避免集中冲刷;
  2. 分散定时任务执行时间,错开持久化、备份、合并任务;
  3. 中间件持久化调整为增量、异步刷盘,减少全量落地。

7. 场景6:K8s容器IO受限,业务读写缓慢(cgroup限流)

7.1. 现象

节点磁盘util不高,但单个Pod内应用读写卡顿,报错IO阻塞。

7.2. 根因

  1. Pod配置limits.readIOPS/limits.writeIOPS磁盘IO配额,触发内核限流;
  2. 多个Pod共享一块磁盘,相互抢占IO资源;
  3. 容器日志输出过多占用磁盘IO,挤压业务读写。

7.3. 排查方案

  1. 进入Pod执行 iostat/iotop 查看容器内IO;
  2. 查看Pod资源yaml中的IO限额配置;
  3. 节点全局iotop定位容器对应进程。

7.4. 解决方案

  1. 根据业务提升Pod IOPS配额,高IO业务单独调度至独享磁盘节点;
  2. 日志sidecar异步采集,容器内关闭同步日志输出;
  3. 使用LocalPV本地SSD给数据库、ES等高IO应用。

8. 场景7:磁盘空间满 / inode耗尽引发IO卡死

8.1. 现象

  1. df查看磁盘100%占用,应用无法写入文件;
  2. touch、日志输出、数据库落盘直接失败;
  3. 若inode占满(大量小文件),df空间充足但无法新建文件。

8.2. 根因

日志未切割堆积、临时文件未清理、海量小文件未删除。

8.3. 排查方案

df -h # 磁盘空间
df -i # inode使用量
find /data -type f -size +1G # 查找大文件

8.4. 解决方案

  1. 配置logrotate自动切割清理过期日志;
  2. 定时清理临时缓存文件、过期备份;
  3. 海量小文件业务改用对象存储归档,定期删除无用碎片文件。

通用标准化排查流程

  1. 全局观测:iostat -x 1 确认磁盘util、iowait、读写IOPS,判断读/写瓶颈;
  2. 定位进程:iotop、pidstat -d 1 找到消耗IO最高的PID;
  3. 追踪文件:lsof /proc/PID/io 查看进程读写的文件/磁盘;
  4. 区分诱因:业务日志/数据库/定时任务/内核脏页/磁盘硬件故障;
  5. 临时止损:暂停定时任务、清理大日志、限流批量写入;
  6. 长期优化:硬件升级、内核参数调优、业务架构拆分、缓存优化、分盘隔离。

关联文档