fio:Flexible IO Tester
1、安装
yum install libaio-devel # 安装异步io引擎
tar xzvf fio-2.1.10.tar.gz
cd fio-2.1.10/
./configure
make
make install
2、使用参数说明
filename=/data/file 测试文件名称.支持文件系统或者裸设备,-filename=/dev/sda2或-filename=/dev/sdb direct=1 bool,true(1)表示测试过程绕过机器自带的buffer。使测试结果更真实。 rw=randread 随机读 rw=randwrite 随机写 rw=randrw 随机混合读写 rw=read 顺序读 rw=write 顺序写 rw=rw 顺序混合读写 rwmixwrite=70 在混合读写的模式下,写占70% bs=4k 单次io的块文件大小为16k bsrange=512-2048 同上,提定数据块的大小范围 size=10G 本次的测试文件大小为10G,以每次4k的io进行测试。 numjobs=30 本次的测试io线程为30. runtime=1000 测试时间为1000秒,如果不写则一直将设定size为10g文件分4k每次写完为止。 ioengine=psync 定义job向文件发起IO的方式 iodepth 一个线程一次提交要提交多少个I/O请求,只对异步I/O引擎有用 group_reporting 关于显示结果的,汇总每个进程的信息。 lockmem=1g 只使用1g内存进行测试 zero_buffers 用0初始化系统buffer nrfiles=8 每个进程生成文件的数量 ioscheduler 在运行之前,尝试将文件所在的设备切换到指定的调度器。????
ioengine:定义job向文件发起IO的方式,不同的引擎使用不同的函数和实现对测试文件发起访问。常用的几个有:
(1)libaio: Linux专有的异步IO,异步引擎。(如果要使用libaio引擎,需要yum install libaio-devel包)
(2)psync/sync: 同步引擎(psync的效果接近异步引擎)
fio --enghelp 查看有哪些ioengine,
fio --enghelp=“引擎名字” 查看对应引擎的帮助
iodepth:
一个线程一次提交要提交多少个I/O请求
这个只对异步I/O引擎有用,因为同步I/O总是会等待提交的I/O请求返回了再提交下一个I/O请求,所以iodepth总是1。
这完全是纯应用层面的行为,和盘的IO queue不是一回事。
3、常用命令
-direct=1
-ioengine=psync -iodepth=1(同步) 或 -ioengine=libaio -iodepth=4/8/16/1024(异步)
-rw=read/randread/write/randwrite/randrw
-rwmixread=70
-bs=4k/1M/4M
fio -filename=/dev/sdc -direct=1 -iodepth 1 -thread -rw=read -ioengine=psync -bs=1M -size=20G -numjobs=24 -runtime=300 -group_reporting -name=sdc_read_4k -output=/home/judy/fio_result/sdc_read_4k
fio -filename=/dev/sdc -direct=1 -iodepth 1 -thread -rw=randread -ioengine=psync -bs=1M -size=20G -numjobs=24 -runtime=300 -group_reporting -name=sdc_randread_4k -output=/home/judy/fio_result/sdc_randread_4k
4、结果
(1)参数说明:
io=执行了多少M的IO
bw=IO带宽
iops=每秒的输入输出量(或读写次数)
runt=线程运行时间
slat=提交延迟(
submission latency),表示盘需要多久将IO提交到kernel做处理
clat=完成延迟(completion latency),表示提交到kernel到IO做完之间的时间,不包括submission latency
lat=响应时间 (
latency),lat = slat + clat,表示从fio将请求提交给内核,再到内核完成这个I/O为止所需要的时间。
cpu=利用率,用户/系统CPU占用率
ctx: context ,进程上下文切换(context switch)次数
majf/minf:主要和次要(major and minor)页面错误数量(page faults)。由于测试是配置成使用直接IO,page faults数量应该极少。
IO depths=io队列
IO submit=单个IO提交要提交的IO数
IO complete=Like the above submit number, but for completions instead.
IO issued=The number of read/write requests issued, and how many of them were short.
IO latencies=IO完延迟的分布
io=总共执行了多少size的IO
aggrb=group总带宽
minb=最小.平均带宽.
maxb=最大平均带宽.
mint=group中线程的最短运行时间.
maxt=group中线程的最长运行时间.
ios=所有group总共执行的IO数.
merge=总共发生的IO合并数.
ticks=Number of ticks we kept the disk busy.
io_queue=花费在队列上的总共时间.
util=磁盘利用率
(2)结果样例分析
[root@node2 fio-2.1.10]# fio -filename=/dev/sdc -direct=1 -iodepth 1 -thread -rw=randrw -rwmixread=70 -ioengine=psync -bs=16k -size=10G -numjobs=30 -runtime=100 -group_reporting -name=mytest -ioscheduler=noop mytest: (g=0): rw=randrw, bs=16K-16K/16K-16K/16K-16K, ioengine=psync, iodepth=1 ... fio-2.1.10 Starting 30 threads Jobs: 30 (f=30): [mmmmmmmmmmmmmmmmmmmmmmmmmmmmmm] [100.0% done] [239.9MB/104.5MB/0KB /s] [15.4K/6659/0 iops] [eta 00m:00s] mytest: (groupid=0, jobs=30): err= 0: pid=172663: Tue Oct 22 11:15:05 2019 # Fio支持把不同的测试聚合,设置分组(group)把IO单独汇总。 read : io=24385MB, bw=249698KB/s, iops=15606, runt=100002msec # IOPS (Input/Output Per Second)即每秒读写次数 #iops * bs = io_bw # 每秒提交次数 * 每次提交数据大小 = 每秒io带宽 clat (usec): min=32, max=20225, avg=1882.78, stdev=1429.20 lat (usec): min=32, max=20225, avg=1882.89, stdev=1429.20 # ipos * lat(s) = jobs * 1(s) # 若同时有r和w,则 r + w = jobs*1(s) clat percentiles (usec): | 1.00th=[ 57], 5.00th=[ 195], 10.00th=[ 478], 20.00th=[ 732], | 30.00th=[ 932], 40.00th=[ 1112], 50.00th=[ 1400], 60.00th=[ 1784], | 70.00th=[ 2352], 80.00th=[ 3216], 90.00th=[ 4016], 95.00th=[ 4640], | 99.00th=[ 5920], 99.50th=[ 6496], 99.90th=[ 7712], 99.95th=[ 8256], | 99.99th=[11840] # "99.99th=[11840]" 表示99.99%请求的响应时间小于等于11840us bw (KB /s): min= 6930, max=10208, per=3.34%, avg=8331.55, stdev=454.58 # 单线程(jobs)的负载 # bw_avg = read_bw / jobs # per = read_bw / bw_avg write: io=10463MB, bw=107134KB/s, iops=6695, runt=100002msec clat (usec): min=30, max=4668, avg=86.21, stdev=40.18 lat (usec): min=31, max=4669, avg=86.80, stdev=40.19 clat percentiles (usec): | 1.00th=[ 42], 5.00th=[ 46], 10.00th=[ 51], 20.00th=[ 61], | 30.00th=[ 67], 40.00th=[ 73], 50.00th=[ 78], 60.00th=[ 83], | 70.00th=[ 91], 80.00th=[ 107], 90.00th=[ 133], 95.00th=[ 155], | 99.00th=[ 201], 99.50th=[ 219], 99.90th=[ 274], 99.95th=[ 318], | 99.99th=[ 972] bw (KB /s): min= 2517, max= 4854, per=3.34%, avg=3573.97, stdev=316.73 lat (usec) : 50=3.07%, 100=22.26%, 250=8.52%, 500=3.52%, 750=7.28% # "50=3.07%"表示 [0~50us),占3.07% lat (usec) : 1000=9.63% lat (msec) : 2=20.55%, 4=18.11%, 10=7.03%, 20=0.02%, 50=0.01% cpu : usr=0.24%, sys=1.12%, ctx=2230918, majf=0, minf=1515 IO depths : 1=100.0%, 2=0.0%, 4=0.0%, 8=0.0%, 16=0.0%, 32=0.0%, >=64=0.0% #表示所有请求的ipdepth都是1.命令中iodepth设成1,所以IO depth在全部时间都是1 # 若iodepth生效,则 ipos * lat(s) ~= jobs * 1(s) * iodepth (前者略小一点) submit : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0% complete : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0% #submit和complete代表同一时间段内fio发送上去和已完成的IO数量。但 iodepth=1 ????? issued : total=r=1560646/w=669604/d=0, short=r=0/w=0/d=0 # 发送的IO数量,r/(r+w) = 70% =rwmixread。单位是???? latency : target=0, window=0, percentile=100.00%, depth=1 # Fio可以配置一个延迟目标值,这个值可以调节吞吐量直到达到预设的延迟目标。四个值分别代表预设的latency_target, latency_window, latency_percentile和iodepth Run status group 0 (all jobs): READ: io=24385MB, aggrb=249698KB/s, minb=249698KB/s, maxb=249698KB/s, mint=100002msec, maxt=100002msec WRITE: io=10463MB, aggrb=107134KB/s, minb=107134KB/s, maxb=107134KB/s, mint=100002msec, maxt=100002msec #汇总输出吞吐量和时间: # io:表示总共完成的IO数量。在基于时间的测试中这是一个变量,在基于容量的测试中,这个值能匹配size参数。 # aggrb:是所有进程/设备的汇总带宽 # minb/maxb表示测量到的最小/最大带宽 # mint/maxt表示测试的最短和最长耗时。在基于时间的测试应该能匹配runtime参数,对于基于容量的测试是一个变量。
Disk stats (read/write): sdc: ios=1560336/669399, merge=0/0, ticks=2919051/49656, in_queue=2969316, util=100.00%
