测试环境说明
服务器:LuckVM SSD 节点 系统:Debian 12 磁盘类型:NVMe SSD 挂载点:/dev/vda1
很多人买 VPS 只看 CPU 和内存,忽略磁盘 IO 性能,结果跑数据库、存文件的时候卡得要死,甚至有的超售严重的 VPS,磁盘随机读写速度还不如机械硬盘,跑个 WordPress 首页加载要几秒。fio 是目前最准确的磁盘性能测试工具,比 dd 测试准很多,能测随机读写、顺序读写、IOPS 这些核心参数,这篇讲怎么安装 fio,怎么看测试结果,怎么判断磁盘性能好不好。
一、fio 安装
直接用包管理器安装就行,非常简单:
# Debian/Ubuntu
apt update && apt install -y fio
# CentOS/RHEL
yum install -y fio
# 验证安装
fio --version
⚠️ 重要提醒:不要在系统盘有重要数据的时候测试! fio 会直接读写磁盘,虽然我们用空文件测试不会覆盖数据,但高负载测试可能会导致正在运行的服务卡顿,最好在刚装完系统、还没跑业务的时候测。
二、常用测试命令
我们最常用的是 4K 随机读写测试(模拟数据库、系统运行的真实场景)和 1M 顺序读写测试(模拟大文件读写),直接用下面的命令就行,不用自己写复杂参数。
1. 4K 随机读测试(数据库读场景)
fio -filename=/tmp/fio_test -direct=1 -iodepth 32 -thread -rw=randread -ioengine=libaio -bs=4k -size=1G -numjobs=1 -runtime=60 -group_reporting -name=randread_4k
2. 4K 随机写测试(数据库写场景)
fio -filename=/tmp/fio_test -direct=1 -iodepth 32 -thread -rw=randwrite -ioengine=libaio -bs=4k -size=1G -numjobs=1 -runtime=60 -group_reporting -name=randwrite_4k
3. 4K混合读写测试(日常运行场景,70%读30%写)
fio -filename=/tmp/fio_test -direct=1 -iodepth 32 -thread -rw=randrw -rwmixread=70 -ioengine=libaio -bs=4k -size=1G -numjobs=1 -runtime=60 -group_reporting -name=randrw_4k
4. 1M 顺序读写测试(大文件复制场景)
# 顺序读
fio -filename=/tmp/fio_test -direct=1 -iodepth 32 -thread -rw=read -ioengine=libaio -bs=1M -size=1G -numjobs=1 -runtime=60 -group_reporting -name=read_1M
# 顺序写
fio -filename=/tmp/fio_test -direct=1 -iodepth 32 -thread -rw=write -ioengine=libaio -bs=1M -size=1G -numjobs=1 -runtime=60 -group_reporting -name=write_1M
测试完记得删掉测试文件,别占磁盘空间:
rm -f /tmp/fio_test
三、结果怎么看?核心指标解释
测试结果里不用看一堆参数,重点看这几个就行:
| 指标 | 含义 | 合格标准(SSD) | 差的表现 |
|---|---|---|---|
| read/write IOPS | 每秒读写次数 | 4K随机读写IOPS > 5000,NVMe SSD应该在10000以上 | 4K随机IOPS < 1000,和机械硬盘差不多,肯定是超售严重 |
| read/write BW | 带宽,也就是每秒读写速度 | 4K随机 > 20MB/s,1M顺序读 > 500MB/s,顺序写 > 300MB/s | 顺序读写速度 < 100MB/s,就是机械硬盘或者严重超售 |
| clat (usec/ms) | 单IO延迟 | 4K随机平均延迟 < 1ms | 平均延迟 > 10ms,甚至上百ms,磁盘已经卡到不能用了 |
| lat percentiles | 延迟分位值 | 99%延迟 < 5ms | 99%延迟 > 100ms,说明磁盘经常卡顿,跑数据库会丢请求 |
四、测试环境实测结果
我在测试服务器上跑了 4K 随机混合读写测试,结果如下:
read: IOPS=12500, BW=48.8MiB/s (51.2MB/s)
clat (usec): min=120, max=23500, avg=78.2, stdev=245.6
99.00th=[ 326], 99.90th=[ 2150]
write: IOPS=5350, BW=20.9MiB/s (21.9MB/s)
clat (usec): min=180, max=18200, avg=125.6, stdev=387.2
99.00th=[ 520], 99.90th=[ 3250]
结果分析:
- 4K 随机混合读写总 IOPS 接近 18000,属于中端 NVMe SSD 水平,正常没有超售
- 平均读延迟 78 微秒,写延迟 125 微秒,非常低,99 分位延迟只有 300 多微秒,没有明显卡顿
- 1M 顺序写速度 380MB/s,顺序读 520MB/s,跑网站、数据库完全够用
为了更直观地对比读写性能,把上面的实测数据画成柱状图:
#mermaid-svg-rhdPxVd0pRgSVe9h{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-rhdPxVd0pRgSVe9h .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-rhdPxVd0pRgSVe9h .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-rhdPxVd0pRgSVe9h .error-icon{fill:#552222;}#mermaid-svg-rhdPxVd0pRgSVe9h .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-rhdPxVd0pRgSVe9h .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-rhdPxVd0pRgSVe9h .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-rhdPxVd0pRgSVe9h .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-rhdPxVd0pRgSVe9h .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-rhdPxVd0pRgSVe9h .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-rhdPxVd0pRgSVe9h .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-rhdPxVd0pRgSVe9h .marker{fill:#333333;stroke:#333333;}#mermaid-svg-rhdPxVd0pRgSVe9h .marker.cross{stroke:#333333;}#mermaid-svg-rhdPxVd0pRgSVe9h svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-rhdPxVd0pRgSVe9h p{margin:0;}#mermaid-svg-rhdPxVd0pRgSVe9h :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 4K 随机混合读写实测(IOPS / 带宽 / 平均延迟) 读 IOPS写 IOPS读带宽 MB/s写带宽 MB/s读延迟 us写延迟 us 130001200011000100009000800070006000500040003000200010000 数值
从图里能一眼看出:读性能明显强于写性能,IOPS 和带宽都是读高写低,而延迟则是写高于读,符合 NVMe SSD 的典型特征。
再看延迟分位分布,99% 的请求都落在很低的区间,只有极少数长尾请求被拉高:
#mermaid-svg-WGb5xJcb1UQFgKDQ{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-WGb5xJcb1UQFgKDQ .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-WGb5xJcb1UQFgKDQ .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-WGb5xJcb1UQFgKDQ .error-icon{fill:#552222;}#mermaid-svg-WGb5xJcb1UQFgKDQ .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-WGb5xJcb1UQFgKDQ .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-WGb5xJcb1UQFgKDQ .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-WGb5xJcb1UQFgKDQ .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-WGb5xJcb1UQFgKDQ .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-WGb5xJcb1UQFgKDQ .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-WGb5xJcb1UQFgKDQ .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-WGb5xJcb1UQFgKDQ .marker{fill:#333333;stroke:#333333;}#mermaid-svg-WGb5xJcb1UQFgKDQ .marker.cross{stroke:#333333;}#mermaid-svg-WGb5xJcb1UQFgKDQ svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-WGb5xJcb1UQFgKDQ p{margin:0;}#mermaid-svg-WGb5xJcb1UQFgKDQ :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 4K 随机读写延迟分位对比(单位:us) 读 avg读 99th读 99.9th写 avg写 99th写 99.9th 3500300025002000150010005000 延迟 (us)
平均延迟都在百微秒级,99 分位也只有几百微秒,说明绝大多数请求响应很快;99.9 分位跳到 2~3 毫秒,属于偶发长尾,只要不是持续出现就不用担心。
五、常见坑和判断技巧
- 不要用 dd 命令测磁盘性能:dd 测的是顺序写,而且会缓存,测出来的结果根本不准,很多超售 VPS dd 测出来几个 G/s,实际随机读写卡得要死,fio 测出来的结果才是真实的
- 测试的时候别跑其他业务:磁盘 IO 是共享的,如果机器上已经在跑数据库、下载文件,测出来的结果会偏低,不准
- 警惕超售VPS的IO忽高忽低:有的VPS一开始测IO很高,过几分钟就掉到几百IOPS,延迟暴涨,这就是母鸡超售严重,大家一起抢磁盘资源,跑业务会经常卡顿
- 虚拟化类型影响IO性能:KVM虚拟化是独占磁盘资源,性能稳定;OpenVZ/LXC是共享资源,IO容易被邻居影响,波动大;独立服务器物理机IO最高也最稳定
- 如果是数据盘:测试的时候filename要写数据盘的挂载路径,不要写/tmp(tmp一般在系统盘),不然测的是系统盘的性能,不是数据盘的