近期进行存储分布式存储性能测试,选择fio进行测试性能,fio测试工具支持同步(pread/pwrite)和异步(libaio)FIO是测试IOPS的非常好的工具,用来对硬件进行压力测试和验证,支持13种不同的I/O引擎,包括:sync,mmap, libaio, posixaio, SG v3, splice, null, network, syslet, guasi, solarisaio 等等。
fio 官网地址:一,FIO安装
yum install fio -y 二,测试案例介绍:############################## 同步i/o ##################################################################3#同步i/o、顺序读:fio -filename=/dev/rbd2 -direct=1 -iodepth 1 -thread -rw=read -ioengine=psync -bs=16k -size=50G -numjobs=30 -runtime=1000 -group_reporting -name=read-psync >read-psync.txt#同步i/o、顺序写:fio -filename=/dev/rbd2 -direct=1 -iodepth 1 -thread -rw=write -ioengine=psync -bs=16k -size=50G -numjobs=30 -runtime=1000 -group_reporting -name=write-psync >write-psync.txt#同步i/o、顺序混合读写:fio -filename=/dev/rbd2 -direct=1 -iodepth 1 -thread -rw=readwrite -rwmixread=50 -ioengine=psync -bs=16k -size=50G -numjobs=30 -runtime=1000 -group_reporting -name=>rw-readwrite-psync.txt#同步i/o、随机读: fio -filename=/dev/rbd2 -direct=1 -iodepth 1 -thread -rw=randread -ioengine=psync -bs=16k -size=50G -numjobs=30 -runtime=1000 -group_reporting -name=randread-psync >randread-psync.txt#同步i/o、随机写: fio -filename=/dev/rbd2 -direct=1 -iodepth 1 -thread -rw=randwrite -ioengine=psync -bs=16k -size=50G -numjobs=30 -runtime=1000 -group_reporting -name=randwrite-psync >randwrite-psync.txt#同步i/o、随机混合读写: fio -filename=/dev/rbd2 -direct=1 -iodepth 1 -thread -rw=randrw -rwmixread=50 -ioengine=psync -bs=16k -size=50G -numjobs=30 -runtime=100 -group_reporting -ioscheduler=noop -name=randrw-psync >randrw-psync.txt ############################## 异步 i/o ##################################################################3#异步 i/o、顺序读: fio -filename=/dev/rbd2 -direct=1 -iodepth 1 -thread -rw=read -ioengine=libaio -bs=16k -size=50G -numjobs=30 -runtime=1000 -group_reporting -name=read-libaio >read-libaio.txt#异步 i/o、顺序写:fio -filename=/dev/rbd2 -direct=1 -iodepth 1 -thread -rw=write -ioengine=libaio -bs=16k -size=50G -numjobs=30 -runtime=1000 -group_reporting -name=write-libaio >write-libaio.txt#异步 i/o、顺序混合读写:fio -filename=/dev/rbd2 -direct=1 -iodepth 1 -thread -rw=readwrite -rwmixread=50 -ioengine=libaio -bs=16k -size=50G -numjobs=30 -runtime=1000 -group_reporting -name=rw-readwrite-libaio >rw-readwrite-psync.txt#异步 i/o、随机读: fio -filename=/dev/rbd2 -direct=1 -iodepth 1 -thread -rw=randread -ioengine=libaio -bs=16k -size=50G -numjobs=30 -runtime=1000 -group_reporting -name=randread-libaio >randread-libaio.txt#异步 i/o、随机写: fio -filename=/dev/rbd2 -direct=1 -iodepth 1 -thread -rw=randwrite -ioengine=libaio -bs=16k -size=50G -numjobs=30 -runtime=1000 -group_reporting -name=randwrite-libaio >randwrite-libaio.txt#异步 i/o、随机混合读写: fio -filename=/dev/rbd2 -direct=1 -iodepth 1 -thread -rw=randrw -rwmixread=50 -ioengine=libaio -bs=16k -size=50G -numjobs=30 -runtime=100 -group_reporting -ioscheduler=noop -name=randrw-libaio >randrw-libaio.txt 说明: filename=/dev/rbd2 测试文件名称,需要测试的盘的某目录。 direct=1 测试过程绕过机器自带的buffer。使测试结果更真实。 }read 顺序读write 顺序写randwrite 随机写randread 随机读rw,readwrite 顺序混合读写randrw 随机混合读写}bs=16k 单次io的块文件大小为16k bsrange=512-2048 同上,提定数据块的大小范围 size=5g 本次的测试文件大小为5g,以每次4k的io进行测试。 numjobs=30 本次的测试线程为30. runtime=1000 测试时间为1000秒,如果不写则一直将5g文件分4k每次写完为止。 ioengine=psync io引擎使用pync方式 rwmixread=30 在混合读写的模式下,读占30% ,默认%50,两个参数同时使用,后者覆盖第一rwmixwrite=30 在混合读写的模式下,写占30% ,默认%50group_reporting 关于显示结果的,汇总每个进程的信息。 lockmem=1g 只使用1g内存进行测试。 zero_buffers 用0初始化系统buffer。 nrfiles=8 每个进程生成文件的数量。 ioscheduler 尝试切换设备托管文件指定的I / O调度器。psync 同步i/o测试libaio 异步i/o测试libaio的读写过程简单说来就是你发出一个读写请求,然后你可以开始做其他事情,当读写过程结束时libaio会通知你你的这次请求已经完成IO引擎:
发起IO的方式。
<1>ioengine=str
定义job向文件发起IO的方式
sync 基本的read,write.lseek用来作定位
psync 基本的pread,pwrite
vsync 基本的readv,writev
libaio Linux专有的异步IO。Linux仅支持非buffered IO的队列行为。
posixaio glibc posix异步IO
solarisaio solaris独有的异步IO
windowsaio windows独有的异步IO
mmap 文件通过内存映射到用户空间,使用memcpy写入和读出数据
splice 使用splice和vmsplice在用户空间和内核之间传输数据
syslet-rw 使用syslet 系统调用来构造普通的read/write异步IO
sg SCSI generic sg v3 io.可以是使用SG_IO ioctl来同步,或是目标是一个sg字符设备,我们使用read和write执行异步IO
null 不传输任何数据,只是伪装成这样。主要用于训练使用fio,或是基本debug/test的目的。
net 根据给定的host:port通过网络传输数据。根据具体的协议,hostname,port,listen,filename这些选项将被用来说明建立哪种连接,协议选项将决定哪种协议被使用。
netsplice 像net,但是使用splic/vmsplice来映射数据和发送/接收数据。
cpuio 不传输任何的数据,但是要根据cpuload=和cpucycle=选项占用CPU周期.e.g. cpuload=85将使用job不做任何的实际IO,但要占用85%的CPU周期。在SMP机器上,使用numjobs=<no_of_cpu>来获取需要的CPU,因为cpuload仅会载入单个CPU,然后占用需要的比例。
guasi GUASI IO引擎是一般的用于异步IO的用户空间异步系统调用接口
rdma RDMA I/O引擎支持RDMA内存语义(RDMA_WRITE/RDMA_READ)和通道主义(Send/Recv)用于InfiniBand,RoCE和iWARP协议
external 指明要调用一个外部的IO引擎(二进制文件)。e.g. ioengine=external:/tmp/foo.o将载入/tmp下的foo.o这个IO引擎
iodepth_low=intLow watermark indicating when to start filling the queue again. Default: iodepth.direct=boolIf true, use non-buffered I/O (usually O_DIRECT). Default: false.fsync=intHow many I/Os to perform before issuing an fsync(2) of dirty data. If 0, don’t sync. Default: 0.这几个参数在libaio的引擎下的作用,文档写的挺明白,但容我再罗嗦下IO请求的流程:libaio引擎会用这个iodepth值来调用io_setup准备个可以一次提交iodepth个IO的上下文,同时申请个io请求队列用于保持IO。 在压测进行的时候,系统会生成特定的IO请求,往io请求队列里面扔,当队列里面的IO个数达到iodepth_batch值的时候,就调用io_submit批次提交请求,然后开始调用io_getevents开始收割已经完成的IO。 每次收割多少呢?由于收割的时候,超时时间设置为0,所以有多少已完成就算多少,最多可以收割iodepth_batch_complete值个。随着收割,IO队列里面的IO数就少了,那么需要补充新的IO。 什么时候补充呢?当IO数目降到iodepth_low值的时候,就重新填充,保证OS可以看到至少iodepth_low数目的io在电梯口排队着。结果总结:例如:read : io(测试了1G的数据)=1024.0MB, bw(带宽)=139643KB/s, iops(每秒钟的IO数)=136 , runt(总运行时间)= 7509msecioengine.list.txtreadwritereadwriterandreadrandwriterandrw二,测试案例介绍:[ cephtest]# more fio-test.sh #!/bin/shFILENAME=/dev/rbd2#RW=$(cat ioengine.list.txt)PIOENGINE=psyncLIOENGINE=libaioBS=16kSIZE=1GNUMJOBS=30RUNTIME=1000NAME=$PIOENGINE.$(date +%Y%m%d)NAME1=$LIOENGINE.$(date +%Y%m%d)echo "###########$(date)###########同步i/o########################################" >iotest.result.$NAME.txtfor i in $(cat ./ioengine.list.txt);do echo ------$i.$NAME--begin--$(date)----- >>iotest.result.$NAME.txt;fio -filename=$FILENAME -direct=1 -iodepth 1 -thread -rw=$i -ioengine=$IOENGINE -bs=$BS -size=$SIZE -numjobs=$NUMJOBS -runtime=$RUNTIME -group_reporting -name=$i.$NAME >>iotest.result.$NAME.txt;echo ------$i.$NAME--end---$(date)----- >>iotest.result.$NAME.txt;echo "" >>iotest.result.$NAME.txt;echo "" >>iotest.result.$NAME.txt;doneecho "###########$(date)###########异步i/o########################################" >iotest.result.$NAME1.txtfor i in $(cat ./ioengine.list.txt);do echo ------$i.$NAME--begin--$(date)----- >>iotest.result.$NAME1.txt;fio -filename=$FILENAME -direct=1 -iodepth 1 -thread -rw=$i -ioengine=$LIOENGINE -bs=$BS -size=$SIZE -numjobs=$NUMJOBS -runtime=$RUNTIME -group_reporting -name=$i.$NAME >>iotest.result.$NAME1.txt;echo ------$i.$NAME--end---$(date)----- >>iotest.result.$NAME1.txt;echo "" >>iotest.result.$NAME1.txt;echo "" >>iotest.result.$NAME1.txt;done##############################################################以顺序读写,随机读写分类 sum_psync sum_libaio###以块大小分类 4k 8k ...###以读写方式分类 read write ...[ caipengtao]# cat bs.txt 4k8k16k32k64k[ caipengtao]# cat rw.txt readwriterandreadrandwrite[ caipengtao]# cat iotest.sh #!/bin/shfile='/rbdtest1/1.txt't=' -size=1M -numjobs=30 -runtime=5 -group_reporting 'for i in `cat bs.txt`do for j in `cat rw.txt` do fio -filename=$file -direct=1 -iodepth 1 -thread -rw=$j -ioengine=psync -bs=$i $t -name=$i.$j >> sum_psync.txt echo '############################' >> sum_psync.txt echo '############################' >> sum_psync.txt rm -rf $file donedonefor i in `cat bs.txt`do fio -filename=$file -direct=1 -iodepth 1 -thread -rw=readwrite -rwmixread=1 -ioengine=psync -bs=$i $t -name=$i.readwrite >>sum_psync.txt echo '############################' >> sum_psync.txt echo '############################' >> sum_psync.txt rm -rf $filedonefor i in `cat bs.txt`do fio -filename=$file -direct=1 -iodepth 1 -thread -rw=randrw -rwmixread=1 -ioengine=psync -bs=$i $t -name=$i.randrw >>sum_psync.txt echo '############################' >> sum_psync.txt echo '############################' >> sum_psync.txt rm -rf $filedonefor i in `cat bs.txt`do for j in `cat rw.txt` do fio -filename=$file -direct=1 -iodepth 1 -thread -rw=$j -ioengine=libaio -bs=$i $t -name=$i.$j >>sum_libaio.txt echo '############################' >> sum_libaio.txt echo '############################' >> sum_libaio.txt rm -rf $file donedonefor i in `cat bs.txt`dofio -filename=$file -direct=1 -iodepth 1 -thread -rw=readwrite -rwmixread=1 -ioengine=libaio -bs=$i $t -name=$i.readwrite >>sum_libaio.txt echo '############################' >> sum_libaio.txt echo '############################' >> sum_libaio.txt rm -rf $filedonefor i in `cat bs.txt`do fio -filename=$file -direct=1 -iodepth 1 -thread -rw=randrw -rwmixread=1 -ioengine=libaio -bs=$i $t -name=$i.randrw >>sum_libaio.txt echo '############################' >> sum_libaio.txt echo '############################' >> sum_libaio.txt rm -rf $filedoneecho 'ceph iotest ok'|mail -s 'ceph test' 参考资料:http://elf8848.iteye.com/blog/2168876