磁盘I/O测试工具-FIO

一、简介

FIO (Flexible I/O Tester)是一款功能强大的I/O性能测试工具,用来对硬件进行压力测试和验证。通过灵活的配置和丰富的命令参数,可以模拟各种复杂的I/O负载场景,帮助用户全面了解存储设备的性能表现。磁盘IO是检查磁盘性能的重要指标,可以按照负载情况分成照顺序读写,随机读写两大类。

FIO Github:https://github.com/axboe/fio

FIO 文档:https://fio.readthedocs.io/en/latest/fio_doc.html

GFIO 是 FIO 的图形监测工具,它提供了图形界面的参数配置,和性能监测图像。可自行了解:https://blog.yufeng.info/archives/tag/fio

二、安装

powershell 复制代码
yum -y install fio
​
# 如需使用 libaio 引擎,需安装
yum -y install libaio-devel

三、常用参数

FIO 的参数非常丰富,可以根据测试需求进行灵活配置。以下是一些详细的参数说明,并已按照参数用途进行了分类:

1.测试任务相关参数

  • --name=测试名称:为测试指定一个名称,方便区分不同的测试。例如:--name=mytest。如果fio --name=job1 --name=job2,建立了两个任务,共享--name=job1之前的参数。--name=job1之后的就是job2任务独有的参数
  • --description=字符串:提供测试项目的描述信息。
  • --filename=测试文件路径:指定测试使用文件的相对路径或者绝对路径,没有的话会自行创建,可以是文件或裸设备。例如:--filename=/path/to/testfile
  • --size=测试文件大小:指定测试文件的大小,支持K、M、G等单位。例如:--size=1G
  • --numjobs=并发任务数:指定并发执行的任务数。例如:---numjobs=4。每个任务都作为一个独立的线程或者进程产生(执行相同工作的进程或者线程)。每个Job(任务)开1个线程,有多少 --name 就开多少个线程。所以最终线程数 = 任务数 (--name 的数量) * --numjobs
  • --ioengine=IO引擎:指定所使用的IO引擎,如libaio、sync等。例如:--ioengine=libaio
  • --iodepth=io队列深度:指定IO队列的深度,默认为1。在一定范围内越大越好,增加队列深度可以看到IOPS不会随着队列深度的增加而一直增加,达到一定值后会有所下降。增加队列深度,可以测试出磁盘的峰值
  • --runtime=测试时间:指定测试的时间长度,单位可以是秒、分钟、小时。当省略单位时间,该数值以秒为单位进行解释。例如:--runtime=60s
  • --ramp_time=预热时间:指定测试前的预热时间。设定在记录任何性能信息之前要运行特定负载的时间。这个用来等性能稳定后,再记录日志结果,因此可以减少生成稳定的结果需要的运行时间。例如:--ramp_time=5s
  • --time_based:参数用于控制FIO的测试模式。当设置time_based时,FIO将确保测试运行指定的时间长度,即使文件已经被完全读写或写入完成。假设你设置了runtime=60s(即测试运行60秒)并且指定了time_based,FIO将确保测试至少运行60秒,即使在这段时间内文件已经被完全读写。在某些情况下,即使设置了time_based,FIO也可能在达到runtime之前停止,例如当遇到错误或达到其他限制条件时
  • --lockmem=内存大小:指定运行时使用的内存大小,例如 --lockmem=1g 表示只使用1g内存进行测试

2.读写相关参数

2.1 常规读写参数

  • --rw=读写模式:
    • read:顺序读
    • write:顺序写
    • randread:随机读
    • randwrite:随机写
    • randrw:随机混合读写(默认50%读和50%写)
    • trim、randtrim:仅支持Linux块设备,用于 Linux 块设备的特殊 I/O 模式
  • --bs=块大小:指定测试的块大小,如--bs=4K
  • --bsrange=块大小范围:指定测试的块大小范围,如--bsrange=512-2048
  • --bssplit=字符串:指定混合块大小的比例,如 bssplit=4k/10:64k/50:32k/40 表示4K占10%,64K占50%,32K占40%
  • --direct=1或0:1表示使用直接IO,绕过文件系统缓存;0表示不使用直接IO
  • --rwmixwrite=数字:在混合读写模式下,指定写的百分比,如 --rwmixwrite=20 表示写占20%

2.2 随机读写相关参数

这些参数影响随机读写的行为,如randrepeat、randseed、offset等,它们决定了随机IO的生成方式和位置

  • randrepeat=True或False:控制随机I/O操作是否可重复,通过固定randseed值实现
    当randrepeat设置为True(或未指定,因为默认值为True)时,使用相同的randseed值(默认为137)将会产生相同的随机I/O位置序列。这意味着在多次运行具有相同randseed值的测试时,I/O操作的位置将是相同的,从而实现了可重复的随机测试。
    如果randseed被设置为一个自定义的值,那么randrepeat将自动变为False,因为每次使用不同的randseed值都会生成不同的随机I/O位置序列。
  • randseed=数字:设置随机数生成器的种子值,用于控制随机I/O操作的位置
    随机数生成器使用种子值作为起点来生成随机数序列。在FIO中,randseed用于控制随机I/O操作的位置。
    通过设置特定的randseed值,可以确保在多次运行测试时产生相同的随机I/O位置序列,从而实现可重复的随机测试。
    如果不指定randseed值,FIO将使用默认值(通常为137)作为种子值。
  • offset=整数数字:指定I/O操作在文件或设备上的起始偏移量,用于控制I/O操作的起始位置
    offset是一个整数参数,可以以字节或块为单位指定。它定义了I/O操作在文件或设备上的起始位置。
    通过设置offset参数,可以控制I/O操作从文件的特定位置开始,而不是从文件的开头开始。这对于测试文件的不同部分或模拟特定的I/O模式(如顺序读/写、随机读/写等)非常有用。

3.其他参数

  • --debug:开启调试模式,输出调试信息
  • --version:显示FIO的版本信息
  • --output=文件名:将测试结果输出到指定文件
  • --group_reporting:汇总每个进程的信息

四、常见测试场景

1.命令行测试

100%随机,100%读,4K

shell 复制代码
fio -filename=/dev/emcpowerb -direct=1 -iodepth 1 -thread -rw=randread -ioengine=psync -bs=4k -size=1000G -numjobs=50 -runtime=180 -group_reporting -name=rand_100read_4k

100%随机,100%写,4K

shell 复制代码
fio -filename=/dev/emcpowerb -direct=1 -iodepth 1 -thread -rw=randwrite -ioengine=psync -bs=4k -size=1000G -numjobs=50 -runtime=180 -group_reporting -name=rand_100write_4k

100%顺序,100%读,4K

shell 复制代码
fio -filename=/dev/emcpowerb -direct=1 -iodepth 1 -thread -rw=read -ioengine=psync -bs=4k -size=1000G -numjobs=50 -runtime=180 -group_reporting -name=sqe_100read_4k

100%顺序,100%写,4K

shell 复制代码
fio -filename=/dev/emcpowerb -direct=1 -iodepth 1 -thread -rw=write -ioengine=psync -bs=4k -size=1000G -numjobs=50 -runtime=180 -group_reporting -name=sqe_100write_4k

100%随机,70%读,30%写 4K

shell 复制代码
fio -filename=/dev/emcpowerb -direct=1 -iodepth 1 -thread -rw=randrw -rwmixread=70 -ioengine=psync -bs=4k -size=1000G -numjobs=50 -runtime=180 -group_reporting -name=randrw_70read_4k

2.参数文件测试

FIO提供了不同场景的压测参数文件,修改其中配置然后直接执行即可

shell 复制代码
fio examples/ssd-test.fio

上面这个参数文件用于测试ssd性能,参数文件内容如下:

其中每一个[]代表一个测试分组(global除外,global中为通用配置),会为每组分别进行测试,其中stonewall指示fio在所有指定的I/O作业(job)都完成其I/O操作之前,不会退出测试程序。这有助于确保测试结果的完整性和准确性,特别是在需要模拟复杂I/O负载场景时。

yaml 复制代码
# Do some important numbers on SSD drives, to gauge what kind of
# performance you might get out of them.
#
# Sequential read and write speeds are tested, these are expected to be
# high. Random reads should also be fast, random writes are where crap
# drives are usually separated from the good drives.
#
# This uses a queue depth of 4. New SATA SSD's will support up to 32
# in flight commands, so it may also be interesting to increase the queue
# depth and compare. Note that most real-life usage will not see that
# large of a queue depth, so 4 is more representative of normal use.
#
[global]
bs=4k
ioengine=libaio
iodepth=4
size=10g
direct=1
runtime=60
directory=/mount-point-of-ssd
filename=ssd.test.file

[seq-read]
rw=read
stonewall

[rand-read]
rw=randread
stonewall

[seq-write]
rw=write
stonewall

[rand-write]
rw=randwrite
stonewall

五、测试结果解读

powershell 复制代码
fio -ioengine=libaio -bs=4k -direct=1 -thread -rw=read -filename=/dev/sda -name="BS 4KB read test" -iodepth=16 -runtime=60

#输出
BS 4KB read test: (g=0): rw=write, bs=1M-1M/1M-1M/1M-1M, ioengine=libaio, iodepth=16
fio-2.8
Starting 1 process
Jobs: 1 (f=1): [W(1)] [100.0% done] [0KB/68198KB/0KB /s] [0/66/0 iops] [eta 00m:00s]
test: (groupid=0, jobs=1): err= 0: pid=4676: Thu Apr  7 17:22:37 2016
  write: io=20075MB, bw=68464KB/s, iops=66, runt=300255msec           #执行多少IO,平均带宽,线程运行时间
    slat (usec): min=51, max=5732, avg=291.11, stdev=262.47           #提交延迟
    clat (usec): min=1, max=2235.8K, avg=239043.28, stdev=153384.41   #完成延迟
     lat (usec): min=367, max=2235.9K, avg=239337.72, stdev=153389.57 #响应时间
    clat percentiles (usec):
     |  1.00th=[  221],  5.00th=[  442], 10.00th=[ 1004], 20.00th=[108032],
     | 30.00th=[228352], 40.00th=[248832], 50.00th=[257024], 60.00th=[268288],
     | 70.00th=[280576], 80.00th=[301056], 90.00th=[342016], 95.00th=[477184],
     | 99.00th=[806912], 99.50th=[864256], 99.90th=[1122304], 99.95th=[1171456],
       | 99.99th=[1646592]
    bw (KB/s): min=  170, max=204800, per=100.00%, avg=68755.07, stdev=27034.84
    lat (usec) : 2=0.01%, 4=0.13%, 50=0.06%, 100=0.26%, 250=1.04%
    lat (usec) : 500=4.53%, 750=2.61%, 1000=1.33%
    lat (msec) : 2=1.18%, 4=0.15%, 10=0.77%, 20=0.77%, 50=1.50%
    lat (msec) : 100=4.43%, 250=23.48%, 500=53.23%, 750=3.09%, 1000=1.30%
    lat (msec) : 2000=0.19%, >=2000=0.01%
  cpu          : usr=0.03%, sys=2.11%, ctx=19066, majf=0, minf=7
  IO depths    : 1=0.1%, 2=0.1%, 4=0.1%, 8=0.1%, 16=103.8%, 32=0.0%, >=64=0.0%   #io队列
     submit    : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%  #单个IO提交的IO数
     complete  : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.1%, 32=0.0%, 64=0.0%, >=64=0.0%  
     issued    : total=r=0/w=20060/d=0, short=r=0/w=0/d=0, drop=r=0/w=0/d=0
     latency   : target=0, window=0, percentile=100.00%, depth=16    #IO完延迟的分布
 
Run status group 0 (all jobs):
  WRITE: io=20075MB, aggrb=68464KB/s(group总带宽), minb=68464KB/s(最小平均带宽), maxb=68464KB/s(最大平均带宽), mint=300255msec(group中线程的最短运行时间), maxt=300255msec(group中线程的最长运行时间)
 
Disk stats (read/write):
  sda: ios=23/41769(所有group总共执行的IO数), merge=0/149(总共发生的IO合并数), ticks=706/9102766(磁盘繁忙的节拍数), in_queue=9105836(花费在队列上的总共时间), util=100.00%(磁盘利用率)

输出参数介绍(详情参考 Fio Output Explained

  • io=执行了多少M的IO
  • bw=平均IO带宽(吞吐量)
  • iops=IOPS,即每秒磁盘 I/O 读写次数
  • runt=线程运行时间
  • slat=提交延迟,提交该IO请求到kernel所花的时间(不包括kernel处理的时间)
  • clat=完成延迟, 提交该IO请求到kernel后,处理所花的时间
  • lat=响应时间
  • bw=带宽
  • cpu=利用率
  • IO depths=io队列
  • IO submit=单个IO提交要提交的IO数
  • IO complete=完成的IO数
  • IO issued=提交的IO总数、较短的IO数、丢弃的IO数
  • IO latencies=IO完延迟的分布
  • io=总共执行了多少size的IO
  • aggrb=group总带宽
  • minb=最小平均带宽
  • maxb=最大平均带宽
  • mint=group中线程的最短运行时间
  • maxt=group中线程的最长运行时间
  • ios=所有group总共执行的IO数
  • merge=总共发生的IO合并数
  • ticks=磁盘繁忙的节拍数
  • io_queue=花费在队列上的总共时间
  • util=磁盘利用率

六、归纳

  • FIO提供了丰富的参数来配置测试方案,可以根据具体需求选择适合的参数组合。
  • 通过指定不同的读写模式、块大小、并发任务数等参数,可以模拟不同的磁盘负载场景,以评估磁盘的性能。
  • 在进行磁盘性能测试时,建议结合实际需求选择合适的参数进行测试,以获得准确的结果。
相关推荐
Xiao Fei Xiangζั͡ޓއއ12 分钟前
一觉睡醒,全世界计算机水平下降100倍,而我却精通C语言——scanf函数
c语言·开发语言·笔记·程序人生·面试·蓝桥杯·学习方法
baijin_cha29 分钟前
机器学习基础04_朴素贝叶斯分类&决策树分类
笔记·决策树·机器学习·分类
波克比QWQ1 小时前
rust逆向初探
笔记·rust逆向
LuckyLay1 小时前
Spring学习笔记_36——@RequestMapping
java·spring boot·笔记·spring·mapping
坚硬果壳_1 小时前
《硬件架构的艺术》笔记(一):亚稳态
笔记·学习
qiyi.sky2 小时前
JavaWeb——Web入门(8/9)- Tomcat:基本使用(下载与安装、目录结构介绍、启动与关闭、可能出现的问题及解决方案、总结)
java·前端·笔记·学习·tomcat
dal118网工任子仪2 小时前
web安全漏洞之ssrf入门
笔记·学习·计算机网络·网络安全
杜若南星4 小时前
保研考研机试攻略(满分篇):第二章——满分之路上(1)
数据结构·c++·经验分享·笔记·考研·算法·贪心算法
金星娃儿7 小时前
MATLAB基础知识笔记——(矩阵的运算)
笔记·matlab·矩阵
B20080116刘实9 小时前
CTF攻防世界小白刷题自学笔记13
开发语言·笔记·web安全·网络安全·php