服务器磁盘I/O过高意味着存储设备的读写速度跟不上应用需求,导致系统响应变慢、服务卡顿。面对这类问题,切忌盲目操作,可以按照快速修复-准确定位-系统优化-不断监控的思路来处置。
第一步:快速应急修复
当监控告警显示磁盘使用率不断接近100%,业务已经出现明显卡顿时,第一是恢复服务。此时不要急于重启服务器,因为重启可能中断正在写入的数据,反而加剧问题。最好的做法是立即登录服务器,使用 iostat -x 1 命令每秒刷新一次磁盘状态,重点看 %util 列。如果该值不断在95%以上,说明磁盘确实已到极限。接着用 iotop -o 找出当前正在进行I/O操作的进程,按读写速率排序。
定位到高I/O进程后,根据情况采取不同措施:如果是数据备份、日志归档这类计划内任务恰好在业务高峰期运行,可以考虑后暂时中止任务;如果是数据库或应用进程,需要进一步分析其内部行为,但此时可先尝试调整该进程的CPU或I/O优先级,如使用 ionice 命令降低其I/O调度优先级,为业务腾出资源。云服务器还可以临时升级磁盘类型或IOPS规格,快速获得性能提升。
第二步:准确找到I/O过高的原因
应急处理稳住局面后,必须深挖导致I/O过高的原因。最常见的原因。
第一类是数据库慢查询。当SQL语句无法有效利用索引,或者需要扫描大量数据时,就会产生大量磁盘随机读。可以开启数据库的慢查询日志,分析执行时间超过1秒的SQL,重点优化其索引设计或拆分复杂查询。
第二类是日志写入过频。许多应用在线上环境仍保留DEBUG级别日志,每秒产生数千条日志记录,对磁盘造成巨大压力。应检查日志配置文件,将线上日志级别调整为INFO或WARN,并启用日志轮转方法,避免单个日志文件无限制增长。
第三类是内存不足导致系统使用交换分区。物理内存耗尽后,操作系统会将部分内存数据换出到磁盘的交换空间,这个过程会产生大量I/O。通过 free -h 查看内存使用情况,如果交换分区使用量不断增长,说明需要增加物理内存,或者调整应用的JVM堆内存参数,避免过度占用。
第四类是应用程序自身的读写流程的问题。如在循环中频繁打开和关闭文件,或者每次请求都从磁盘读取相同的配置文件。这类问题需要通过代码审查发现,并引入缓存层(如Redis)或使用内存文件系统来缓解。
第五类是文件系统碎片化或磁盘本身性能不足。机械硬盘在随机读写场景下性能会急剧下降,此时更换为SSD往往能带来数量级的提升。

第三步:系统化性能测试
定位并修复问题后,需要通过压测来证实优化效果,并摸清当前磁盘的性能上限。Linux下最权威的磁盘压测工具是 fio。测试随机读写性能可以模拟数据库情形,使用块大小4K、队列深度64、混合读写比例的参数;测试顺序读写性能可以模拟日志写入场景,使用块大小1M、纯写入方式。测试时必须加上 direct=1 参数绕过系统缓存,否则测出的数据没有参考作用。
将测试结果和磁盘标称的IOPS和吞吐量进行对比,如果实际值远低于理论值,需要检查磁盘连接方式、文件系统类型和挂载参数。如XFS文件系统在高并发情形下表现优于EXT4,SSD硬盘使用 noop 调度器可以减少不必要的I/O排序开销。
第四步:建立监控和预警
一次排查只能解决当前问题,建立长效监控机制才能防患于未然。推荐采用Prometheus加Grafana的组合方案:在每台服务器上部署Node Exporter采集磁盘标准,Prometheus定期拉取数据,Grafana展示可视化趋势图。监控的标准包括磁盘使用率、读写速率、I/O等待时间和队列长度。当磁盘使用率连续5分钟超过80%,或者I/O等待时间超过30毫秒时,就应该触发告警通知运维人员介入。