磁盘 IO 慢排查与优化指南:iostat、hdparm 定位瓶颈,让磁盘不再拖后腿


网站突然变卡、数据库查询变慢、装软件半天没动静——很多时候不是 CPU 不够,而是磁盘 IO 成了瓶颈。磁盘 IO 是服务器最容易忽略又最影响体验的一项:磁盘读写跟不上,所有依赖磁盘的操作都会变慢。这篇文章教你用工具定位磁盘 IO 瓶颈,并给出切实可行的优化方案。

一、为什么磁盘 IO 会变慢

磁盘 IO(Input/Output)就是磁盘的读写能力。它慢的原因通常有几类:

  • 磁盘本身慢:机械盘(HDD)远慢于固态盘(SSD),入门 VPS 可能是机械盘
  • IO 被打满:某个进程疯狂读写,占满了磁盘带宽
  • 磁盘将满:空间不足导致碎片化加重、性能下降
  • 文件系统问题:inode 用完、日志盘满
  • 缓存交换频繁:内存不足,频繁使用 swap 换进换出

二、先看服务器整体负载

1. 看系统负载和等待:

uptime
# 查看 load average 三个值,如果很高说明负载重

2. 用 top 查看 wa(等待 IO)占比:

top

按 1 看每个核的 CPU,重点关注 wa(I/O wait,等待磁盘的时间)。如果 wa 持续很高(比如 30% 以上),说明磁盘 IO 是瓶颈。

三、用 iostat 定位磁盘读写情况

iostat 是查看磁盘 IO 最常用的工具:

# 安装
apt install -y sysstat    # Ubuntu/Debian
yum install -y sysstat    # CentOS/Rocky

# 每秒刷新一次,共看 5 次
iostat -x 1 5

重点看这几列:

  • %util:磁盘利用率,接近 100% 说明磁盘被打满
  • r/s、w/s:每秒读/写次数
  • rkB/s、wkB/s:每秒读/写的数据量
  • await:平均每次 IO 等待时间,越大越慢(毫秒)
  • svctm:每次 IO 实际服务时间

判断方法:

现象 结论
%util 接近 100%,await 很大 磁盘被打满,IO 是瓶颈
%util 不高但 await 大 可能是单个请求量大或磁盘老化
r/s、w/s 都很高 有进程在大量读写

四、找出谁在疯狂读写磁盘

定位到磁盘 IO 高之后,要找出是哪个进程在搞。

1. 用 iotop 看进程级 IO:

apt install -y iotop   # Ubuntu/Debian
yum install -y iotop   # CentOS/Rocky

iotop

iotop 实时显示每个进程的磁盘读写速率,一眼就能找出吃磁盘的进程。

2. 用 ps 找可疑进程:

ps aux --sort=-%cpu | head -n 10

3. 查看日志是否异常写入:

du -sh /var/log/*   # 看哪个日志文件巨大
tail -f /var/log/syslog  # 看是否有异常刷日志

五、检查磁盘空间和 inode

磁盘空间或 inode 用完,也会导致写入失败和性能骤降。

# 查看磁盘空间
df -h

# 查看 inode 用量(文件系统存文件数量的上限)
df -i

处理建议:

  • 空间满:清理无用的日志、备份、临时文件,详见本站磁盘清理教程
  • inode 满:删除大量小文件(如缓存图片),或给 inode 扩容

六、检查 swap 交换是否频繁

内存不足时,系统会把内存页换到磁盘(swap),频繁交换会严重拖慢磁盘 IO。

# 看 swap 使用情况
free -h

# 用 vmstat 看 si/so(swap 换入/换出)
vmstat 1 5

如果 si/so 持续不为 0,说明内存紧张、系统在频繁换页,此时"磁盘慢"其实是"内存不足"导致的。解决方向是增加内存、优化进程占用或调整缓存策略。

七、测量磁盘真实性能

想了解磁盘的基础性能上限,可以做基准测试:

# 简单测写速度
dd if=/dev/zero of=/tmp/test bs=1M count=1024 conv=fdatasync

# 用 hdparm 测读速度
hdparm -t /dev/sda       # 需要 root,/dev/sda 改成你的设备名

# 专业压测工具 fio(最准确)
apt install -y fio
fio --filename=/tmp/fio_test --rw=randrw --bs=4k --size=1G --numjobs=4 \
  --iodepth=32 --runtime=30 --group_reporting --name=test

机械盘随机读写通常几十 MB/s,SSD 数百 MB/s 到 GB 级。如果测出来明显低于同样本应水平,可能磁盘老化或有问题,可以考虑联系服务商或换磁盘。

八、磁盘 IO 优化方案

1. 关闭不必要的 atime 访问时间更新(减少写)

挂载时加 noatime:

# /etc/fstab 中挂载参数添加 noatime
/dev/sda1 / ext4 defaults,noatime 0 0

2. 调优 IO 调度算法

SSD 适合 noop/none,机械盘用 deadline:

# 查看当前调度算法
cat /sys/block/sda/queue/scheduler

# 临时切换为 none(SSD)
echo none > /sys/block/sda/queue/scheduler

3. 增加缓存 / 用内存盘

高频读的目录可以通过 tmpfs 放内存加速;数据库的缓存池调大。但要注意内存盘数据易失,仅适合缓存类。

4. 数据库优化

MySQL 之类数据库频繁读写磁盘。调整缓冲池大小、开启合理刷盘策略、避免全表扫描,能有效降低磁盘压力(参考本站 MySQL 教程)。

5. 升级硬件/方案

如果 IO 长期紧张且优化无效,考虑: - 机械盘换成 SSD(性能提升最明显) - 增加内存减少 swap - 数据库读写分离开,读走缓存/从库

九、IO 飙升的应急处理

突发 IO 打满、网站濒临卡死时:

# 1. 先用 iotop 找到元凶进程
iotop

# 2. 若是异常进程(如被入侵挖矿、疯狂爬虫),果断处理
kill -9 进程PID

# 3. 清理撑爆磁盘的日志
truncate -s 0 /var/log/syslog

# 4. 必要时重启 MySQL/PHP 释放缓存
systemctl restart mysqld

总结

排查磁盘慢的核心逻辑:看负载(uptime/top)→ 看磁盘(iostat)→ 找进程(iotop)→ 查空间(df)→ 测性能(dd/fio)→ 针对性优化。大多数"服务器变慢"问题,要么是磁盘被打满、要么是内存不足导致频繁 swap、要么是磁盘空间/inode 用尽。先定位再优化,才能对症下药。配合本站的 VPS 性能测试和磁盘清理教程,维护磁盘健康不再难。


手机扫码阅读

微信或手机浏览器扫一扫,随时随地随心阅读与分享

PHP 性能优化教程:PHP-FPM 参数调优、OPcache 开启与慢日志定位,网站秒开

curl 命令详解与实战:请求调试、文件下载、接口测试,一个命令全搞定

评 论
更换验证码