目录
fio简介:
fio基本概念:
I/O类型
块大小(Block Size)
I/Oszie
I/O引擎(I/O engine)
I/O深度(I/O depth)
线程/进程(Threads/Processes)
fio常用参数:
ioengine=str
filename=str
runtime=runtime
size=int
ramp_time=int
readwrite=str, rw=str
rwmixread=int
startdelay=int
numjobs=int
thread
blocksize=int[,int], bs=int[,int]
blocksize_range=irange[,irange][,irange], bsrange=irange[,irange][,irange]
blocksize_unaligned, bs_unaligned
iodepth=int
direct=bool
exec_preren=str
exec_postrun=str
nrfiles=int
filesize=int
openfiles=int
description=str
time_based
create_only=bool
unlink=bool
stonewall,wait_for_previous
其它参数
--output=filename
--output-format=format
--showcmd=jobfile
fio是一个IO测试工具,可以运行在Linux、Windows等多种系统之上,可以用来测试本地磁盘、网络存储等的性能。
配置灵活多样,支持多客户端并发测试(server、client模式),支持文件级、对象级存储测试,更对多种主流的存储如GlusterFS、CephFS等有专用测试引擎。测试结果包括IOPS、BW、lat等多种数据
fio可以指定要测试的I/O的类型,读/写,顺序/随机,最基本的也就有了4种读写规则、顺序读、顺序写、随机度、随机写。
读写的区别就不说了,一般情况下,机械硬盘的写入速度要比读取速度慢,有时可能有数倍只差。而对于顺序与随机,机械硬盘对于随机读写,尤其是小文件的随机读写,性能非常差。主要是由于访问位于物理硬盘盘面的不同位置的小文件需要大量的时间进行寻道,而机械硬盘的寻道相对于读写是非常慢的,所以也就造就了机械硬盘的随机小文件很差的性能。而固态硬盘,由于其没有机械硬盘的物理结构,所以其物理小文件性能可以碾压机械硬盘。并且随着以固态硬盘位核心而设计的接口和协议的出现(M.2、PCIe接口 NVMe协议等)即使大文件固态硬盘也能完全碾压机械硬盘了。
一般来说块大小为 512B 4K 16K .....1M、4M 这样的扇区大小(512字节)的倍数,小于16K的文件,一般算作小文件,大于16K的文件属于大文件。
一次读写多大的数据,即每次io请求要读写多少数据,一般是1K/4K....1M/4M等大小。
使用I/O引擎就是使用某些函数,以某些特定方式来访问存储,不同的I/O引擎有不同的使用场景。比如windows只能用windowsaio Linux可以使用 libaio,sync,psync等
简单的理解就是一次提交要提交多少个I/O请求,不过这个只对异步I/O引擎有用,因为同步I/O总是会等待提交的I/O请求返回了再提交下一个I/O请求,所以iodepth总是1。
随着iodepth的增大在一定范围内,带宽、io延时会增加,超过一定范围后带宽增加缓慢,延时继续会增加。延时增加的原因是因为随着iodepth增加都需花更多的时间等待请求io数量达到iodepth数值后,才会真正把io请求发送给存储,所以平均每一个io的延时都会增大了。
带宽之所以会提高可能主要与网络延时有关,如果每次只发一个io请求,那么完成这一次io请求的时间 = 收发延时 + io请求执行时间,如果没有延时则每秒客户端可以完成1000次请求,但是加上收发延时后,每秒的请求次数必然减少。但是如果将每次io请求数量增加,比如一次发10个请求,那么这10次请求时间花费 = 等待10个io请求 + 1次收发延时 + 10次io请求执行时间,而10次单个的io请求时间 = 10次收发延时+ 10次io请求执行时间。如果等待10个io请求时间低于9次收发延时,那么每秒能够完成的io请求时间就会增加,也就会增加带宽
简单的理解就是一次提交要提交多少个I/O请求,不过这个只对异步I/O引擎有用,因为同步I/O总是会等待提交的I/O请求返回了再提交下一个I/O请求,所以iodepth总是1
定义job向文件发起IO的方式,不同的引擎使用不同的函数和实现对测试文件发起访问。有很多(在安装了fio的系统上可以通过fio --enghelp查看有哪些ioengine,并且通过fio --enghelp=“引擎名字”查看对应引擎的帮助),就不一一介绍了。常用的几个有:
libaio Linux专有的异步IO,异步引擎。(需要注意的是如果你是编译安装的fio,则需要在fio编译前安装libaio的相关库,否则编译出来的fio是没有这个引擎的)
psync/sync 同步引擎
windowsaio 如果在windows下运行fio则需要使用这个引擎
fio一般会根据job线程号,文件号来给文件起名。如果想让多个想成共享一个文件,指定一个代替默认名字的名字,如果i/o引擎是基于文件的,你可以使用:来分开不同的文件 ' - '是保留的名称,表示是stdin或stdout,取决于读/写方向设置一般测试块设备级(磁盘)时候把 filename=str 指定为设备名如:filename=/dev/sda1 测试的就是/dev/sda1磁盘,如果要测试文件级设备,可以将 filename 指定到挂载好的目录中,如filename=/mnt/nfs/test,注意filename指定的是一个文件(filename=/mnt/nfs/test 测的是/mnt/nfs挂载目录中生成test文件进行测试)写成目录fio会报error=Is a directory。
一般测试文件级设备或目录,最好实用directory=/mnt/nfs/参数fio一般会根据job线程号,文件号来给文件起名。如果想让多个想成共享一个文件,指定一个代替默认名字的名字,如果i/o引擎是基于文件的,你可以使用:来分开不同的文件 ' - '是保留的名称,表示是stdin或stdout,取决于读/写方向设置
限制运行时间
如果不指定时间的话,可以指定测试文件的大小(如size=int),快会进行定量的测试
本次job的总共的io大小。除非你设置了runtime(运行时间)或 nrfiles(运行文件数量) 和 filesize(运行文件大小)被设定,fio将会一直运行到这个(size=int)大小的数据被传输完毕,这些数据将会被平均分到job定义的文件中,如果没有设定这个大小,fio将会使用整个磁盘空间,如果这个文件不存在的话(filename=str没有给出),大小一定要给出。也可以给一个1-100的百分比大小,如果size=20%,fio将会使用整个磁盘的20%用来设置本次测试所测的文件大小使用时发现fio会先生成你指定大小的文件,然后在进行测试(如果之前有生成的与本次同名的就不会再生成一次了),实际测试时可以定时测试(runtime=int)或定量测试(size=int)
nrfiles和fileszie可以指定生成几个(nrfiles=int)多大(filesize=int)的文件进行测试,所以测试过程中生成的文件总量size=nrfiles*fileszie
如果设置了这个参数,fio将会在做任何有关性能的纪录之前,(job)运行你指定的时间,用于在记录前使设备性能稳定,从而最大限度的减少稳定性能的运行时间,注意这个job运行时间会是(ramp_time+runtime)。
有时设备测试之前需要运行一会性能才稳定,加上这个参数就可以让设备运行一会而不记录,这个时间是包括在runtime时间之内的。
I/O类型
read 顺序读
write 顺序写
randread 随机读
randwrite 随机写
rw 混合顺序读写
randrw 混合随机读写对于混合的读写,默认的比例是50/50(另外可以在读写类型的字符串后面添加一个“:
”,比如rw=randread:8,这个是用来指定每次随机读前有关偏移量之类的东西的,一般也用不到,有需要的可以自己看官方文档)
混合随机读写中读所占的百分比,初始值是50
通过这个参数既可以控制读写的比例了,比如如果想要读写3:7则可以设置rwmixread=70
fio启动几秒后再启动job。只有在job文件包含几个jobs时才有效,是为了将某个job延时几秒后执行,可以让多个job之间有一定的时间间隔。
与ramp_time的区别就是startdelay是job任务完全不运行,就是闲等,ramp_time是指job开始执行你指定的任务了,但是ramp_time时间内不会做记录
本次任务克隆的数量(线程/进程 执行相同的任务),默认值1。
可以根据自己的主机性能指定执行测试任务的job的数量,可以得到更加接近“满载”状态下的性能指标
使用pthread_create创建线程代替使用fork创建进程
使用 threads 在一定程度上可以节省系统开销
指定一个变化的i/o块,i/o的大小总是最小i/o的整数倍(除非设置了blocksize_unaligned参数),如果只设置了一个变化区间,这项设置将会同时作用于读和写。但是可以使用逗号分开指定(读和写),例如(bsrange=1k-4k,2k-8k),(其它的见blocksize项)
bs可以指定特定大小的i/o块大小,bsrange则可以指定一个变化的i/o块大小,再性能测试中,这个参数可以模拟一个更真实的i/o请求。
指定一个IO块范围,除非设置了blocksize_unaligned参数,否则生成的IO块大小将是最小的IO的整数倍。使用逗号分隔读写的区间描述,如:
bsrange=1k-4k,2k-8k
即随机生成1k-4k的文件用于读,2k-8k的文件用于写,而且如果你没有指定blocksize_unaligned,则本例中只会生成1k、2k、3k、4k的测试文件用于读取,2k、4k、6k ......。如果不想把读写分开指定,则可以写为bsrange=1k-8k,那么就会生成1k-8k的文件同时用于读写。
如果设置了这个参数,那么fio将产生任何bsrange指定的区间中任意大小的测试文件,但是此设置在direct 的I/O通常需要分区对齐/*(我也不太懂这分区对齐是啥意思)*/
文件上I/O模块的数量,注意大于1的iodepth对于同步io来说是没用的的(除非verify_async被使用),即使是异步引擎也可能会被操作系统限制,达不到指定的iO深度,这可能会发生在使用libaio引擎且direct没有设置成1时,因为操作系统的缓存可能不是异步的。注意fio的输出中的IO depth分布区间,是否符合设置的预期。默认值:1
这个选项可以提高I/O的并发数量,但并不是数值越大测出来性能就越好,具体的数值可以多尝试几次来确定。
如果设置为真,将不使用I/O缓存(通常是O_DIRECT).初始值为否
文件及存储如nfs,再向服务器中写入数据时,有事会发现写入速度甚至会远大于理论带宽数值,这就是由于拷贝调用了缓存,设置direct=1则可以不使用缓存,否则有事可能会测出来很吓人的性能数据。
运行job之前,通过过system执行指定的命令
运行job之前,通过过system执行指定的命令
exec_preren与exec_postrun可以再job运行前后执行一些命令,配合你的测试。
用于指定每一个job的要产生多少个大小为filesize的文件,注意每一个独立的job都会产生int数量的文件。
单个文件的大小,可以是一个范围,在这种情况下,fio将会在一个范围内选择一个大小来决定单个文件大小,如果没有设置的话,所有的文件将会是同样的大小。
使用nrfiles和filesize这两个参数,可以使每个job(每个任务的每个线程或进程)生成指定数量特定大小的文件,这样对于后端是分布式的文件系统,模拟会更真实。(如果是通过size=int和filename=str两个参数,生成的会只有一个名为str,大小为size的文件)
注意此参数与bs参数的区别,bs是控制一次访问的块的大小的,而filesize是控制被访问的文件的大小的,例如bs=4K, fileszie=1M,fio则会以每次4K的请求大小来访问1M的文件
在同一时间可以同时打开的文件数目,默认同nrfiles相等,可以设置小一些,来限制同时打开的文件数目。
可以通过设置它模拟指定的负载。
可以个输出做标识。
如果设置的即使job已被完全读写或写完,也会执行完runtime规定的时间。它是通过循环执行相同的负载来实现的。加上这个参数可以防止job提前结束。
如果设置为true的话,fio将只会生成测试需要的文件但是不执行任务,可以用它来创建大量的文件(配合nrfiles和filesize)。
job运行完毕后会删除运行过程中产生的测试文件。但可能会使测试文件被反复创建,浪费测试时间。
在一个有多个job的文件中,可以多个job逐个执行(stonewall后面将是一个新的group),通常用于需要执行多种不同的任务时,让任务按顺序执行
这两个参数其实功能基本相同,只是使用的位置有所不同,stonewall一般放在一个job任务的末尾,wait_for_previous一般放在一个job任务的开头
这些是fio的一些配置参数,一般不卸载job文件中,如果使用命令行,一般也写在命令行最后。
将测试结果输出到文件中,
如果指定了这个参数,屏幕上就不会有输出了。
设置fio输出结果的格式,一般用到的有normal(默认就是它),json(写程序处理比较方便)
将job文件的内容转换为命令行参数