Linux 服务器磁盘 IO 过高
当你发现 Linux 服务器响应越来越慢,数据库查询延迟飙升,甚至 SSH 都卡顿 —— 大概率是磁盘 IO 过高了。
磁盘 IO(输入输出)过载时,CPU 大量时间花在等待磁盘完成读写,系统吞吐量骤降。
本文直接从零开始,教你诊断、优化并验证磁盘 IO 性能,每一步都附命令和配置片段。
准备工作与诊断工具
先确保你已通过 SSH 登录服务器,并拥有 root 或 sudo 权限。
我们需要安装两个核心工具:iostat(来自 sysstat 包)和 iotop(可选,用于按进程查看 IO)。
在 CentOS/RHEL 系统上执行:
sudo yum install -y sysstat iotop
Ubuntu/Debian 系统执行:
sudo apt install -y sysstat iotop
安装完成后,运行 iostat -x 1(每隔1秒显示一次扩展信息)。
重点关注这三列:
- %util:磁盘忙碌百分比,接近 100% 表示 IO 饱和。
- await:平均每次 IO 等待时间(毫秒),越大说明排队越严重。
- svctm:平均服务时间(毫秒),若远小于 await,说明瓶颈在排队而非磁盘本身。
如果 %util 持续 >80%,则确认磁盘 IO 过高,需要进一步优化。
核心优化操作:对症下药
根据诊断结果,不同场景采用不同优化手段。
下面列出最常用且见效快的六种方法。
1. 更换 IO 调度器(减少 IO 排队)
查看当前调度器:
cat /sys/block/sda/queue/scheduler
输出类似 noop [deadline] cfq,方括号内是当前生效的调度器。
对于 SSD 或虚拟化磁盘,推荐切换为 noop 或 none:
echo noop > /sys/block/sda/queue/scheduler
永久生效需要修改 grub 内核启动参数(如 elevator=noop),或使用 Ubuntu 的 udev 规则。
2. 调整文件系统挂载参数(减少元数据写入)
修改 /etc/fstab 中对应分区挂载选项,增加 noatime,nodiratime:
/dev/sda1 /data ext4 defaults,noatime,nodiratime 0 0
然后重新挂载:mount -o remount /data。
这能避免每次读取文件时更新访问时间,减轻写 IO。
3. 优化 IO 的 sysctl 参数(提升吞吐量)
在 /etc/sysctl.conf 末尾追加:
vm.dirty_ratio = 30
vm.dirty_background_ratio = 10
dirty_ratio 控制脏页占内存的百分比,达到此值后进程会强制同步写入;dirty_background_ratio 是后台 pdflush 开始写入的阈值。
适当调高可以聚合写入,降低 IO 峰值。
执行 sysctl -p 生效。
4. 分离日志与数据(针对数据库或高写入应用)
若服务器运行 MySQL 或 PostgreSQL,将事务日志(redo log、WAL)放在单独的高速磁盘(如 SSD),数据文件放在 HDD。例如在 MySQL 中调整 innodb_log_group_home_dir 指向 SSD 挂载点。这能显著减少主存储的随机写压力。
5. 启用 RAID 卡缓存与回写策略(硬件 RAID 环境)
使用 storcli 或 MegaRAID 管理工具,开启 WriteBack 缓存并设置 CachedIO。对于 BBU(电池备份)正常的环境,这通常能提升数倍随机写性能。命令示例(以 LSI 卡为例):
storcli /c0 set wrcache=WT
注意:若 BBU 失效,回写模式可能丢数据,请谨慎操作。
6. 调整进程 IO 优先级(紧急情况下应急)
使用 ionice 降低非关键进程的 IO 优先级:
ionice -c 2 -n 7 -p PID
-c 2 表示 best-effort,-n 7 是最低优先级。
通常用于给数据库或 Web 服务保留高优先级。
避坑指南:新手最容易犯的错
- 调完参数不验证:修改 /sys 下参数后重启会重置,一定要确认永久生效方式。
- 盲目调高 dirty_ratio:超过物理内存的 50% 可能导致系统抖动,建议先以 30% 起步。
- 在 BBU 失效下启用回写缓存:意外断电时数据丢失风险很大,务必确认电池状态。
- 忽略热点文件分布:优化前先用
iostat -x -p sda查看每个分区的负载,有时瓶颈只在特定分区。 - 一发现问题就换硬件:软件调优往往能解决 80% 的 IO 问题,先尝试以上方法。
验证优化效果与持续监控
调整后再次运行 iostat -x 1 5,观察 %util 是否下降,await 是否明显减少。
更专业的可用 fio 做基准测试:
fio --name=test --ioengine=libaio --rw=randwrite --bs=4k --size=1G --numjobs=4 --runtime=30 --group_reporting
对比优化前后的 IOPS 和延迟。
同时通过 top 查看 wa(IO wait)占比,若从 >20% 降至 <5%,说明优化有效。
日常监控建议使用 dstat 或 vmstat 1 持续关注 IO 状态,也可集成到 Prometheus + Grafana 实现告警。
如果你正在处理 Linux 服务器磁盘 IO 过高,如何优化存储性能?
建议先按本文步骤完整执行,再根据自己的环境做微调;
遇到异常时优先回看避坑和高频问题部分。
熟练之后,你也能快速定位 IO 瓶颈并给出针对性方案。