磁盘 IO 性能与优化
用 iostat、iotop、fio 判断磁盘是不是瓶颈,并通过文件系统、挂载参数与写入模式的调整把 IO 性能榨出来。
服务器变慢时,很多人先怀疑 CPU 或内存,但真正的元凶常常是磁盘 IO。数据库卡顿、备份期间整机发木,背后往往都是磁盘在排队。本文教你用几条命令看清 IO 状况,并给出可直接照做的优化手段。命令以 Ubuntu/Debian 为主。
先看 IO 利用率和等待
iostat 来自 sysstat 包,是最常用的 IO 观察工具:
sudo apt install sysstat
iostat -x 2
-x 输出扩展指标,2 表示每 2 秒刷新。重点看这几列:
- %util:设备繁忙百分比,接近 100% 说明磁盘几乎没有空闲。
- await:每次 IO 的平均等待时间(毫秒),SSD 通常个位数,持续几十毫秒以上要警惕。
- r/s、w/s:每秒读写次数(IOPS)。
- aqu-sz:平均队列长度,长期大于 1 说明请求在排队。
想知道是哪个进程在狂读写,用 iotop:
sudo apt install iotop
sudo iotop -oPa
-o 只显示有实际 IO 的进程,-a 累计统计,一眼就能揪出「写盘大户」。
用 fio 测真实读写能力
想知道磁盘到底能跑多少 IOPS 和吞吐,用 fio 做基准测试:
sudo apt install fio
# 4K 随机读写,考察 IOPS
fio --name=randrw --ioengine=libaio --direct=1 \
--rw=randrw --bs=4k --size=1G --numjobs=1 \
--runtime=30 --group_reporting
# 顺序读,考察吞吐(MB/s)
fio --name=seqread --ioengine=libaio --direct=1 \
--rw=read --bs=1M --size=1G --runtime=30 --group_reporting
请在数据盘的目录里跑,测完删掉生成的测试文件,避免占空间或影响线上业务。
SSD 与 HDD 的差别
机械硬盘(HDD)靠磁头寻道,随机 IOPS 只有一两百;SSD 无机械结构,随机 IOPS 轻松上万,await 也低一个数量级。判断你的盘是哪种:
lsblk -d -o name,rota # ROTA=1 是 HDD,ROTA=0 是 SSD/NVMe
结论很简单:对随机小 IO 敏感的负载(数据库、消息队列),尽量放 SSD。
常见优化手段
- 数据库放 SSD:MySQL、PostgreSQL、Redis 持久化都是随机 IO 大户,放 SSD 上收益最直接。
- noatime 挂载:默认每次读文件都会更新访问时间,凭空产生写入。在 /etc/fstab 给分区加 noatime(如 defaults,noatime),再 sudo mount -o remount /,读多写少场景明显减负。
- 选合适文件系统:通用场景 ext4 稳妥,大文件/快照需求可选 xfs,别用老旧或不匹配的文件系统。
- 减少频繁小写:把大量小写合并成批量写,日志开缓冲、应用层加写队列,能显著降低 IOPS 压力。
- 加缓存:内存充足时 Linux 页缓存会自动缓存热数据;应用层再加 Redis/Memcached,把大量读请求挡在磁盘之外。
怎么判断是不是 IO 瓶颈
一个快速法则:iostat -x 里 %util 长期接近 100% 且 await 明显偏高,同时 top 里 CPU 的 wa(iowait)占比高,基本可以确定是 IO 瓶颈。若 %util 很低但系统仍慢,问题多半在 CPU 或网络,别在磁盘上白费功夫。
小结
看 IO 用 iostat -x 与 iotop,测能力用 fio,区分 SSD/HDD 看 rota。优化的核心是「把随机 IO 放 SSD、减少不必要的写、用缓存挡住读」。先用数据定位瓶颈,再对症下药,才能把服务器的磁盘性能真正发挥出来。