fio(Flexible I/O Tester)是 Jens Axboe 开源的一款磁盘性能压测工具,它通过模拟各种I/O模式来评估存储设备的真实能力。在众多指标中,4K随机读写的IOPS(每秒输入输出操作次数)最受关注,因为它直接反映了存储系统在小数据块、高并发场景下的表现,而这正是数据库、消息队列、容器集群等业务的典型负载特征。本文将围绕fio的测试方法、主流云服务器的4K IOPS表现以及测试中的注意事项展开详细讨论。

一、为什么4K IOPS是云服务器磁盘性能的核心指标
理解IOPS之前,先要明白存储设备的两类典型工作模式。顺序读写是大块数据连续传输,比如拷贝一个几十GB的视频文件,考验的是吞吐量(MB/s);随机读写则是数据分散在磁盘各处,每次只读写很小的数据块,比如数据库根据索引查找记录,考验的是IOPS。
为什么偏偏是4K这个尺寸?因为Linux文件系统的页大小通常为4KB,MySQL的InnoDB引擎默认页大小也是16KB(底层拆分为多次4K访问),绝大多数小块随机访问最终都会落到4K粒度上。因此4K随机读写的IOPS成为行业通用的基准测试项,各大云厂商在产品文档中标注的性能上限,基本也都是以4K IOPS为口径。
需要注意的是,IOPS高不代表一切。延迟(latency)同样关键:一块盘能做到10万IOPS但P99延迟达到50ms,对延迟敏感的业务来说可能还不如一块5万IOPS但延迟稳定在1ms以内的盘。所以做压测时,fio报告中的lat和clat百分位数据要一起看,不能只盯着IOPS数字。
二、fio标准测试命令与参数详解
工欲善其其事必先利其器,先安装fio。CentOS可以执行yum install fio,Ubuntu执行apt-get install fio。下面是一套业内常用的4K随机读写测试命令:
# 4K随机读测试,iodepth=32,使用libaio引擎
fio -filename=/dev/vdb -direct=1 -iodepth=32 \
-thread -rw=randread -ioengine=libaio -bs=4k \
-size=10G -numjobs=1 -runtime=60 \
-group_reporting -name=rand_read_4k
# 4K随机写测试
fio -filename=/dev/vdb -direct=1 -iodepth=32 \
-thread -rw=randwrite -ioengine=libaio -bs=4k \
-size=10G -numjobs=1 -runtime=60 \
-group_reporting -name=rand_write_4k
# 混合读写测试(7读3写,接近多数数据库负载)
fio -filename=/dev/vdb -direct=1 -iodepth=32 \
-thread -rw=randrw -rwmixread=70 -ioengine=libaio -bs=4k \
-size=10G -numjobs=1 -runtime=60 \
-group_reporting -name=rand_rw_4k几个关键参数必须理解到位。-direct=1表示绕过操作系统Page Cache直接读写磁盘,不开启的话测出来的是内存速度,毫无意义;-ioengine=libaio使用Linux原生异步I/O,这是云盘测试的标准姿势;-iodepth控制队列深度,云盘是网络存储,低队列深度下根本跑不满性能,一般建议32起步;-bs=4k指定块大小为4KB。
还有一个容易被忽略的细节:-filename指向裸设备(如/dev/vdb)时结果是纯存储性能,指向一个文件时则包含文件系统开销。两者结果会有差异,测试时务必说明清楚测试对象,否则不同来源的数据没有可比性。
测试结果重点关注这几行输出:IOPS列就是每秒操作数,lat列是平均延迟,clat后面的百分位数(如99.00th)表示99%的请求延迟低于该值。对于数据库类业务,P99延迟往往比IOPS更能说明问题。
三、主流云服务器4K IOPS表现参考
各云厂商的云盘按性能分档,以下数据综合官方文档与实测整理,供参考。注意实际数值会受实例规格、地域、测试方法影响,同一块云盘挂在不同规格的实例上,能跑到的IOPS上限也不同,因为IOPS是消耗实例网络带宽的。
| 云厂商 | 盘类型 | 容量档位 | 4K随机读IOPS参考 | 4K随机写IOPS参考 |
|---|---|---|---|---|
| 阿里云 | ESSD PL1 | 1000GB以上 | 约50000 | 约50000 |
| 阿里云 | ESSD PL3 | 1261GB以上 | 约1000000 | 约1000000 |
| 腾讯云 | 增强型SSD云硬盘 | 动态计算 | 最高约130000 | 最高约130000 |
| 华为云 | 极速型SSD | 动态计算 | 最高约128000 | 最高约128000 |
| AWS | gp3 | 独立配置 | 基准16000起 | 基准16000起 |
| AWS | io2 | 独立配置 | 最高256000 | 最高256000 |
从表中可以看出几个规律。第一,ESSD PL3这类顶级云盘与普通SSD云盘的差距可达两个数量级,但价格同样悬殊,选型时要结合业务实际IOPS需求。第二,AWS的gp3支持IOPS与容量、带宽解耦配置,灵活性较高,适合精准控制成本的场景。第三,各家高端云盘的IOPS上限通常与容量挂钩,容量越大可获得的IOPS配额越高,这是因为云厂商按容量分配存储后端资源。
另外要注意,本地盘类产品(如部分计算型实例自带的NVMe SSD本地盘)的4K随机性能往往远超云盘,单盘可达数十万甚至上百万IOPS,且延迟更低更稳定。但本地盘数据不持久,实例停机或迁移数据会丢失,只适合缓存、临时数据处理等场景。
四、为什么你测出来的数字与排行榜对不上
经常有人拿着fio结果质疑厂商数据造假,其实多数情况下是测试姿势的问题。第一个常见原因是队列深度不足:iostat里看着util才30%,fio只跑到几万IOPS,很可能是iodepth设置太低,或者numjobs太少,没能把存储队列压满。
第二个原因是测试目标错了。有人用fio -filename=/tmp/test.img测试,结果操作系统把文件缓存在了内存里,测出来几十万IOPS——那是内存的速度,不是盘的。务必加上-direct=1并确认文件大于内存或者直接测试裸设备。
第三个原因是实例规格限制。云盘挂载在低配实例上时,实例的vCPU处理中断和网络转发的性能会成为瓶颈。比如一块100万IOPS的ESSD PL3挂在一台2核实例上,实际可能只能跑到30万。测试高端云盘务必选择高规格实例,并且观察top中%soft(软中断)指标。
第四个原因是预热问题。部分云盘首次全盘写入会有初始化过程,冷盘直接压测前期数据偏低,建议先做一轮顺序写预热再跑随机测试,结果会稳定得多。
五、从排行榜到选型:如何用好4K IOPS数据
排行榜只能作为参考起点,真正落地选型时要回归业务需求。先梳理业务的读写比例和IOPS需求量:一台写多读少的MySQL,重点看随机写IOPS和混合负载下的延迟;一个日志采集系统更关心顺序写吞吐;Redis这类对延迟极其敏感的服务,则应该优先考虑P99延迟指标而非峰值IOPS。
建议的落地流程是:先用业务高峰期的真实QPS估算所需IOPS(一条SQL往往对应多次4K IO),放大1.5倍作为冗余;再用fio按本文第二节的命令压测候选云盘,重点观察混合读写下的P99延迟是否达标;最后在预发环境跑真实业务压测验证。三步走下来,比单纯比较排行榜数字靠谱得多。
总结一下,fio的4K IOPS测试是评估云服务器存储能力最基础也最有效的手段,但数字本身不是目的。理解测试原理、控制好变量、结合延迟数据综合判断,才能把云盘性能真正转化为业务价值。