fio 命令在 Linux 系统中的应用示例
fio 命令在 Linux 系统中的应用示例
FIO(Flexible I/O Tester)是一个开源的 I/O 性能测试工具,可用于模拟顺序读写和随机读写负载。通过 fio 可以获取存储设备的关键性能指标,如 IOPS(每秒 I/O 操作数)、吞吐量(带宽)和延迟等。下面按照顺序读、顺序写、随机读、随机写、混合读写和并发测试等不同场景,分别给出命令示例、典型输出,并逐项解释各指标含义和可能反映的问题。
顺序读测试
-
fio 命令示例:
fio -direct=1 -iodepth=64 -rw=read -ioengine=libaio -bs=1M -size=1G -numjobs=1 -runtime=60 -name=seq_read_test
。该命令以 1MB 的块大小对设备进行顺序读测试,iodepth=64 表示使用较深的请求队列以充分利用带宽。 -
典型输出:fio 输出会显示类似
READ: IOPS=15.1k, BW=59.1MiB/s (61.0MB/s) ...
的行,以及后续的延迟统计信息(见下图)。输出包括每秒 I/O 操作数(IOPS)、读写带宽(BW)和延迟分布等指标。图示:顺序读测试的典型输出示例,展示了读 IOPS、带宽(BW)、以及各阶段延迟(slat/clat/lat)统计。
-
指标解释:输出中包含以下主要指标:
- IOPS:表示每秒完成的读操作数。IOPS 越高意味着单位时间内完成的 I/O 操作越多,读写并发性能越好。
- 吞吐量(BW):表示每秒读写的数据量。带宽通常以 MiB/s(Mebibyte/s)或 MB/s(Megabyte/s)为单位,反映持续的数据传输能力。在顺序读场景下,带宽是关键指标,高带宽表示设备能快速传输大量数据。
- 延迟(Latency):输出中会有两种延迟统计:slat(提交延迟,即从 fio 发出请求到请求进入内核的时间)、clat(完成延迟,即从请求进入内核到完成的时间)以及总延迟 lat。通常我们关注 clat 或总 lat,因为它们代表应用程序感受到的响应时间。例如,
clat (usec): min=... avg=...
给出 I/O 完成延迟的最小、平均值等;后面的百分位行(如 95%、99%)反映高延迟请求的占比,是评估尾部延迟的重要依据。 - CPU 和队列利用率:输出还显示 CPU 使用率(usr/sys)和 I/O 队列深度分布等,可用于判断是否存在 CPU 或 I/O 队列瓶颈。
-
结果分析:顺序读通常能达到较高的带宽,但 IOPS 相对较低,因为块较大时每秒操作数少。若发现带宽远低于设备标称值,可能原因包括 I/O 队列深度不足、文件系统/缓存干扰、网络瓶颈(对于网络盘)等。如使用机械硬盘,更大的数据区域会导致磁头寻道距离变大,从而提升平均寻道时延,降低 IOPS。另外,增加队列深度通常能提高顺序读的带宽和 IOPS 峰值,但也会增加 I/O 在队列中的等待时间,从而总体上拉高响应延迟。需要在吞吐和延迟之间进行权衡。例如,一次提交多个 I/O(增加 numjobs 或 iodepth)可以减少磁头移动距离、提高 IO 利用率,但会使部分请求排队等待更长时间。
顺序写测试
-
fio 命令示例:
fio -direct=1 -iodepth=64 -rw=write -ioengine=libaio -bs=1M -size=1G -numjobs=1 -runtime=60 -name=seq_write_test
。该命令以 1MB 块大小进行顺序写测试。 -
典型输出:输出格式与顺序读类似,会显示
WRITE: IOPS=... BW=...
,后跟 slat、clat、lat 等统计信息。【以下输出示例】write: IOPS=106k, BW=415MiB/s (435MB/s)(40.5GiB/100002msec)slat (usec): min=3, max=14296, avg=23.86...clat (nsec): min=993, max=20735k, avg=257999.15...lat (usec): min=30, max=20773, avg=281.97......
(示例来源于 fio 测试输出)
-
指标解释:同样适用于顺序写。IOPS 表示每秒写操作次数,BW 表示每秒写入的数据量。clat 和 lat 表示写请求的完成延迟,总体与顺序读相同,只是场景不同。顺序写时,数据通常被直接写入设备,若未加
direct=1
则可能先写入缓存后再落盘,因此测试中通常使用-direct=1
以绕过缓存获得真实带宽。 -
结果分析:顺序写的带宽通常接近顺序读,但有时会略低,因为写操作可能受到磁盘写入机制(如刷盘、写缓存策略)的影响。如果带宽明显低于预期,可能原因包括写入缓存未充分使用、文件系统元数据更新开销、或硬盘写入延迟较大等。另一方面,过高的队列深度下,提交给磁盘的写入请求堆积也会增加写入延迟。与顺序读类似,机械硬盘在写入更大区域时也会因为寻道增加而降低 IOPS。低 IOPS 或 高延迟 往往反映存储设备已接近性能极限或存在瓶颈,可能需要检查硬件、I/O 调度器或调整测试参数(如降低块大小)来定位问题。
随机读测试
图示:随机读测试的典型输出示例,包括 IOPS、带宽、延迟等指标。
-
fio 命令示例:
fio -direct=1 -iodepth=32 -rw=randread -ioengine=libaio -bs=4K -size=1G -numjobs=1 -runtime=60 -name=rand_read_test
。该命令以 4KB 小块进行随机读测试,iodepth=32 允许一定并发来逼近设备 IOPS 极限。 -
典型输出:输出会包含类似
READ: IOPS=15.1k, BW=59.1MiB/s ...
的统计行,如上图所示【22†】;此外会列出 slat、clat、lat 的最小/平均/最大和百分位信息。随机读场景的 IOPS 和平均延迟尤为重要。 -
指标解释:与顺序读一样,IOPS 和 BW 分别表示每秒完成的读操作数和每秒读数据量。由于块小,随机读的 IOPS 往往更关注。延迟指标包括提交延迟和完成延迟,总延迟(lat)近似等于提交延迟加完成延迟。在随机测试中,**clat 的平均值和高百分位(如 95%、99%)**尤为重要,因为它反映大多数请求的响应时间和尾部延迟情况。
-
结果分析:理想情况下,高 IOPS(例如千级以上)和低延迟(单个位数毫秒或以下)说明随机读取性能良好。若 IOPS 显著低于预期或延迟异常增大,可能原因包括:存储介质类型(如机械硬盘随机 I/O 本身就慢;SSD 情况更好)、硬件繁忙、队列过高导致排队、或 I/O 调度器问题等。特别地,机械硬盘在随机读大范围数据时,磁头寻道时间增加会显著降低 IOPS。此外,如使用网络存储(NAS/NFS),还可能受到网络带宽或协议延迟的限制。总之,高延迟 可能暗示设备处于饱和或存在抖动,需要检查硬件规格和系统负载;低 IOPS 则可能说明测试未充分并行或设备达到性能上限。
随机写测试
-
fio 命令示例:
fio -direct=1 -iodepth=32 -rw=randwrite -ioengine=libaio -bs=4K -size=1G -numjobs=1 -runtime=60 -name=rand_write_test
。采用 4KB 块进行随机写测试,iodepth=32 以增加 I/O 并发度。 -
典型输出:示例输出如下(部分截取):
write: IOPS=50.2k, BW=196MiB/s (205MB/s)(19.1GiB/100002msec)slat (usec): min=3, max=10742, avg=23.21...clat (nsec): min=825, max=21466000, avg=573943.92...lat (usec): min=50, max=22154, avg=597.26...
其中 IOPS=50.2k 表示每秒写操作数约为 5.02 万次,BW=196MiB/s 表示每秒写入数据约 196 MiB,clat 平均约 0.57ms。
-
指标解释:IOPS、吞吐量、延迟等指标含义同前。通常随机写 IOPS 受制于磁盘随机写能力和缓存机制。输出中的 clat(完成延迟)往往比随机读更高,这是因为写入可能涉及数据刷盘或日志更新。百分位延迟(输出中的
clat percentiles
)能帮助判断大部分写请求的响应情况。 -
结果分析:高 IOPS 表示设备对随机写的支持较好。若发现随机写延迟显著高于读取延迟,常见原因包括:存储设备缓存刷新策略、写放大效应、磁盘寻道或写入放缓等。此外,如果缓存被占满或多线程冲突(高并发写时),IOPS 会下降、延迟上升。在混合负载下(后述),过多写请求也会拖慢读性能。与随机读类似,可以通过调整 iodepth 和 jobs 来平衡 IOPS 与延迟。
混合读写测试
-
fio 命令示例:
fio -direct=1 -iodepth=32 -rw=randrw -rwmixread=70 -ioengine=libaio -bs=4K -size=1G -numjobs=1 -runtime=60 -name=mixed_test
。该命令设置 70% 读、30% 写的随机混合负载,其中-rwmixread=70
指定读操作占比为 70%。你也可以使用-rw=rw
(等比例顺序读写)来测试顺序混合读写。 -
典型输出:FIO 在混合读写模式下会分别列出读和写的统计信息。例如,输出可能包含:
READ: IOPS=30.0k, BW=117MiB/s ... WRITE: IOPS=12.9k, BW=50.5MiB/s ...
还会有一个总线带宽和总 IOPS 的聚合行,如
IOPS=42.9k, BW=167MiB/s
(示例)。上图显示读写总带宽和 IOPS 的计算方式:IOPS=读IOPS+写IOPS,BW=读BW+写BW。 -
指标解释:输出中分别给出读操作和写操作的 IOPS/BW/延迟,以及混合后的总计值。总 IOPS 和总带宽反映了系统在混合负载下的总体吞吐能力。例如,
IOPS=25k
代表读写操作合计每秒 2.5 万次。需要注意读写比例对结果的影响:读操作通常会被缓存更多,写操作可能导致缓存刷新,读写比例不同会显著改变各自的性能表现。 -
结果分析:混合读写测试有助于模拟更真实的负载场景,观察读写竞争对性能的影响。一般来说,当写占比较高时,总 IOPS 和带宽会下降,延迟上升,因为写请求可能阻塞读请求或触发额外的刷新操作。反之,读占比高时写入能力成为瓶颈。若测试中发现 总 IOPS 降低而延迟增加,可能是因为某一方向的 I/O 压力导致磁盘忙碌。例如,随机写多时写缓存填满,会拖累读写性能。分析混合测试结果时,应结合读写分开的延迟分布来判断系统瓶颈所在。
并发测试(多线程/多作业)
-
fio 命令示例:
fio -direct=1 -iodepth=32 -rw=randread -ioengine=libaio -bs=4K -size=1G -numjobs=4 -runtime=60 -group_reporting -name=multi_job_test
。其中-numjobs=4
表示同时启动 4 个并发线程或进程执行相同测试,-group_reporting
使输出汇总显示所有作业的综合指标。 -
典型输出:并发测试的输出会显示各作业的累计结果,或者如上图中所示只显示一个合计行。如果使用
-group_reporting
,最终会出现类似IOPS=100k, BW=390MiB/s ...
的聚合统计,表示 4 个线程的总 IOPS 和总带宽(为所有线程求和)。 -
指标解释:多作业模式下,同样关注 IOPS、BW 和延迟等指标,只是这些值代表了所有并发作业的总和。使用
-group_reporting
可以直接查看总 IOPS。系统会同时为每个作业统计 slat/clat/lat,然后合并,或单独输出各线程延迟分布。需要注意,numjobs
增加相当于增加并行度,有时可提高总吞吐,但也会使系统负载和延迟增加。 -
结果分析:增加并发(线程/作业数)通常能提高 I/O 利用率,获得更高的整体吞吐。例如,从 1 个作业扩展到多个作业后,总 IOPS 会增加,但单个请求的平均延迟也可能上升。如上图所述,如果一次只提交一个 I/O(单线程),单个请求响应快但总吞吐低;并发多请求可以提高带宽但也会产生更多排队等待。在实际测试中,应根据应用特点调整并发参数:对高并发业务(如数据库、多用户读写)应测试较高
numjobs
,同时关注 95%/99% 延迟以保证稳定性;如果延迟敏感(如在线事务应用),可能需要限制并发度以降低响应时间。