服务器磁盘 IO 很高时,为什么 CPU 看起来并不忙?

服务器监控里最容易让人误判的一类问题,是 CPU 和内存看起来都不算高,但网站、接口或后台操作却明显变慢。很多时候,真正拖住业务的不是计算能力,而是磁盘 IO。磁盘读写一旦排队,应用线程、数据库查询、日志写入和缓存落盘都会被迫等待,用户看到的就是页面卡顿、请求超时、后台保存很慢,甚至偶发 502 或 504。

服务器磁盘 IO 很高时,为什么 CPU 看起来并不忙?

先分清 IO 高和 CPU 高

CPU 高通常意味着程序正在大量计算,或者有进程陷入循环、压缩、编译、加密等计算密集任务。磁盘 IO 高则不同,它更像是“大家都在等硬盘”。进程未必消耗很多 CPU,因为它们多数时间卡在读写等待上。监控里如果看到 CPU 使用率不高,但 load average 持续升高、iowait 明显增加,就要优先怀疑磁盘 IO。

这也是很多新手排障时容易困惑的地方:明明 CPU 还有空闲,为什么网站还是慢?原因在于服务器性能不是只由 CPU 决定。一次请求可能要读取程序文件、查询数据库、写入访问日志、更新缓存、生成临时文件,只要其中某个磁盘操作排队,整个请求链路都会被拖住。

哪些现象说明可能是磁盘卡住

磁盘 IO 问题通常不会只表现为一个服务慢,而是多个依赖磁盘的环节同时变慢。比如 WordPress 后台保存文章很久才响应,数据库查询偶尔超时,上传文件时卡住,日志写入延迟变高,SSH 登录后执行简单命令也有停顿。这类现象如果和 CPU、内存占用不匹配,就很值得检查磁盘。

另一个信号是慢得不稳定。CPU 算力不足时,业务通常会稳定地慢;而磁盘排队常常是阶段性的:备份开始、日志切割、数据库批量写入、爬虫流量突然增加,都会让 IO 短时间冲高。等这些任务结束后,网站又看起来恢复正常,所以排查时一定要结合时间线。

先看 iowait 和磁盘利用率

Linux 上可以先用 tophtop 看 CPU 行里的 wa,也就是 iowait。如果 iowait 长时间偏高,说明 CPU 有不少时间在等磁盘响应。接着用 iostat -x 1 看具体磁盘设备,重点关注 %utilawaitr/sw/srkB/swkB/s

%util 接近 100% 不一定代表磁盘带宽被跑满,但通常说明设备一直有请求在处理;await 变高则说明请求平均等待时间变长。对于网站服务器来说,如果 await 从平时的几毫秒变成几十甚至上百毫秒,数据库和文件读写体感就会明显下降。

找出是谁在读写磁盘

确认 IO 异常后,下一步不是立刻重启服务,而是找出最忙的进程。可以用 iotop -oPa 观察哪些进程正在持续读写,也可以用 pidstat -d 1 按进程查看读写速率。常见嫌疑包括数据库进程、备份脚本、日志分析任务、图片压缩任务、搜索索引任务、杀毒扫描、异常爬虫触发的大量访问日志。

如果是 MySQL 或 MariaDB 导致 IO 高,不要只看数据库进程名,还要继续分析慢查询、临时表、索引缺失和大批量写入。很多数据库 IO 问题本质上不是磁盘太差,而是查询方式让数据库反复扫表、排序、写临时文件,最终把磁盘拖满。

数据库、日志和备份最常见

中小型网站里,磁盘 IO 高最常见的三个来源是数据库、日志和备份。数据库方面,缺索引、慢查询、频繁更新、临时表落盘都会制造大量随机 IO。日志方面,如果访问量增加、错误日志刷屏、调试日志没关,磁盘写入会持续累积。备份方面,全量打包、数据库导出、远程同步如果没有限速,很容易在业务高峰期把磁盘压满。

排查时建议先问三个问题:异常发生时有没有备份任务?错误日志有没有突然变大?数据库慢查询有没有集中出现?这三个问题往往比盲目升级配置更有效。尤其是定时备份,很多人设置后就忘了,直到每天某个时间网站固定变慢,才发现备份和业务访问撞在一起。

不要急着只升级 CPU 内存

如果瓶颈是磁盘,单纯升级 CPU 或内存未必解决问题。更合理的处理方式是先减少不必要 IO:关闭无用调试日志,限制备份时间和速率,清理异常任务,优化数据库索引,把缓存目录、上传目录和数据库压力分开评估。对读多写少的网站,可以通过页面缓存、对象缓存、CDN 缓存减少后端文件和数据库访问。

如果业务确实长期依赖高频读写,再考虑更合适的磁盘类型、云盘性能档位或独立数据库方案。选择云服务器时,也不能只看 CPU 核数和内存大小,磁盘 IOPS、云盘类型、快照策略和同机房网络稳定性都要一起看。像 速维云服务器 这类云服务方案,在选型时就应该把业务读写特点、访问地区和后续扩容空间一起评估,而不是只按最低价格下单。

临时止血怎么做

线上已经明显卡顿时,处理顺序要稳。第一步是确认不是磁盘空间满了,可以用 df -hdf -i 检查容量和 inode。第二步看 iostatiotop,找到最明显的读写来源。第三步评估能不能暂停低优先级任务,例如备份、批量压缩、日志分析、测试脚本,而不是直接重启数据库或 Web 服务。

如果必须重启,也要先判断是否会造成更长时间恢复。例如数据库在大量写入时强行重启,可能触发恢复过程,短时间内 IO 更高。更安全的方式通常是先限流、暂停非核心任务、清理明显异常日志,再逐步恢复服务。

长期优化看三条线

第一条线是监控。至少要记录 CPU、内存、磁盘容量、inode、iowait、磁盘 await、数据库慢查询和关键接口响应时间。只有形成时间线,才能判断 IO 高是访问增长、定时任务、数据库问题还是异常流量导致。

第二条线是任务治理。备份、日志切割、图片处理、统计分析、搜索索引都应该避开业务高峰,并设置限速或分批执行。第三条线是架构拆分。访问量变大后,可以把数据库、文件存储、缓存、静态资源逐步拆开,不要让所有读写都挤在同一块系统盘上。

结语

服务器变慢不一定是 CPU 不够,也不一定是内存不够。磁盘 IO 高时,进程大量时间都在等待读写完成,所以监控上常常出现“CPU 不忙,业务很慢”的矛盾现象。排查这类问题,要先看 iowait 和磁盘延迟,再定位具体进程和任务,最后结合数据库、日志、备份和业务访问时间线做判断。

真正可靠的运维思路,不是看到慢就立刻升级配置,而是先找到瓶颈在哪里。只有知道慢在计算、内存、网络还是磁盘,后面的优化和选型才不会走偏。

© 版权声明
THE END
喜欢就支持一下吧
点赞7 分享