Fio测试工具

记录常用的使用配置。
Fio官方文档点击这里

1. 常用Job文件

1.1. 设置I/O模型随机比、读写比

1
2
3
4
5
6
7
8
9
10
11
12
13
[rw_1]
ioengine=libaio
direct=1
bs=8k
rw=rw
rwmixread=70
;rate_iops=560,240
;设置iops上限
percentage_random=70
filename=/dev/mapper/mpathb:/dev/mapper/mpathc
iodepth=32
time_based
runtime=300

1.2. 生成不可重删压缩的文件/数据

1
2
3
4
5
6
7
8
9
10
[Files]
ioengine=libaio
direct=1
bs=256k
rw=write
refill_buffers
directory=/mnt/poc
nrfiles=100
filesize=1g
iodepth=32

1.3. 生成压缩文件/数据

1
2
3
4
5
6
7
8
9
10
11
12
13
[comp-files]
ioengine=libaio
direct=1
directory=/mnt/comp
nrfiles=100
filesize=100m
rw=write
bs=512k
iodepth=8
buffer_compress_percentage=70
;设置压缩块大小(非必须),默认512
buffer_compress_chunk=1024
buffer_pattern= "zyzzzzz"

1.4. 生成重删文件/数据

如果是文件系统,也可以重复拷贝不同的文件。

1
2
3
4
5
6
7
8
9
10
[dedup-files]
ioengine=libaio
direct=1
directory=/mnt/dedup
nrfiles=100
filesize=100m
rw=write
bs=512k
iodepth=8
dedupe_percentage=20

1.5. 绑定CPU、空载CPU

1
2
3
4
5
6
7
8
9
10
11
12
[writeDisk]
ioengine=sync
direct=1
bs=4k
rw=write
cpus_allowed=2
filename=/dev/sdb

[cpu_load]
ioengine=cpuio
cpuload=70
cpus_allowed=2

2. 参数

2.1. 命令行参数

1
2
3
4
5
6
--eta-newline=time #几秒换行
--status-interval=t # 每隔t秒输出统计信息
--parse-only # 分析job文件语法
--output=/dir/xx.log # 设置测试结果输出文件
--showcmd # 转换为命令行模式
--status-interval #设置测试结果输出间隔

2.2. Target file/device

1
2
3
4
5
6
7
8
filename
directory
size
nrfiles
create_serialize=0 # 并行生成文件,默认值是1,为串行生成文件
create_only=1 # 只创建文件,而不进行IO读写测试
pre_read=bool # 预读数据到内存,不支持non-seekable I/O engines(e.g.network,splice)
file_service_type #random,roundrobin,sequential

2.3. I/O type

1
2
3
4
5
6
7
8
9
10
11
12
13
direct=bool # 直接I/O,绕过系统缓存
buffered=bool # 与direct相反
atomic=bool # 原子操作I/O,只有Linux平台支持
unified_rw_reporting=bool # 读写合并数据一起给出 report mixed
randrepeat=bool # 设置随机I/O模型下随机数生成器可预测反复模式,以便测试模型可以重复,默认 开启
allrandrepeat=bool # 所有I/O模型,默认关闭
randseed=int # 为了能够孔控制一连续的输出
rate_iops=560,240 # 控制读写比例(IOPS)
rwmixread=70 # 控制整个负载的读写比例。
# 设置rwmixread=70 ,两块盘读写=7:3,153.28 65.80。
# 如果设置了rate_iops=800,总负载读写iops=800,单个盘的读写的iops=400.
# 如果rwmixread=70,rate_iops=800.总负载的读/写 iops=800,盘1 r/w iops=7:3,盘2 r/w iops=3:7. 这是因为rate_iops=800的意思是读写都是800。fio优先满足这一指标。
# 如果需要控制读写比例,且还要控制IOPS上限。使用 rate_iops=700:300,总负载读写700:300.各盘细微差异

说明:
原子操作与竞争操作

2.4. Buffers and memory

1
2
3
4
5
6
7
8
zero_buffers # 用全零初始化缓存,Fio默认用一段随机数据初始化,随后重复利用(也就是说,并不是不可压缩的文件,也不是全零文件)
refill_buffers # Fio每一次提交I/O都会重新填满缓存,以产生随机数据保证生成的文件具有充分的随机性;使用 zero_buffers 参数时,不会生效;默认关闭,如果有需要会重复利用缓存数据;当使用 verify,buffer_compress_percentage或者dedupe_percentage参数时,refill_buffers 自动开启。
scramble_buffers=bool # refill_buffers对服务器消耗太大的话,用这个也有一定效果,但是没那么“聪明”,只能避免一些傻瓜的压缩算法。Slightly scramble buffers on every IO submit # This is not enough to defeat more clever block compression attempts, but it will stop naive dedupe of blocks. Default: true.
buffer_compress_percentage # 如果设置这个参数,Fio会尝试去提供满足要求的I/O缓存内容(写);Fio利用固定样式数据生成混合随机数据,固定样式可以是zeros 或者buffer_pattern参数定义的样式;buffer_pattern参数会稍微偏斜压缩率?;设置该参数为一个数值(非100)时,会自动开启refill_buffers,以减少相邻块相似数据合并压缩的可能性;
buffer_compress_chunk # Size of compressible region in buffer
buffer_pattern=0xdeadface # 数据内容
norandommap
randrepeat

2.5. 变量调用 Environment variables

方便调试
$ SIZE=64m NUMJOBS=4 fio jobfile.fio //命令行中设定变量值

1
2
3
4
5
6
; -- start job file --
[random-writers]
rw=randwrite
size=${SIZE} #相当于 size=64m
numjobs=${NUMJOBS} #相当于 numjobs=4
; -- end job file --

2.6. gfio 可视化

gfio

1
2
3
4
5
$ yum install gtk2
$ yum install gtk2-devel
# 2. 编译时,加上 --enable-gfio参数:
$ ./configure --enable-gfio
gfio

fio2gnuplot绘制曲线

1
2
3
4
5
6
7
8
9
10
# 安装gnuplot
yum install gnuplot
# fio测试:
# 添加参数`--write_bw_log=fio-test write_iops_log=fio-test write_lat_log=fio-test`
# 将这个test-fio_bw.1.log修改成test-fio_bw.log,fio2gnuplot会默认在当前目录下寻找 \*_bw.log文件
# 使用下面的命令绘制:
fio_generate_plots bw
# 或者
fio2gnuplot -b -g
# 将图片导出即可看到曲线图。

2.7. 利用blktrace+fio回放块设备的真实活动负载

注意:回放相当于重新写入,会覆盖数据

1
2
3
4
5
mount -t debugfs none /sys/kernel/debug
blktrace -d /dev/sdb
blkparse -i sdb -d sdb.blktrace.bin
fio --name=replay --filename=/dev/sdb --direct=1 --read_iolog=sdb.blktrace.bin
btt -i sdb.blktrace.bin

2.8. 多节点联机测试

需要配置好SSH免密登录,防火墙设置。

1
2
3
4
# 服务端开启Fio服务 
fio --server &
# 客户端
fio --output=tmp.log --client=localhost node1.fio --client=172.0.72.239 node2.fio \--client=172.0.72.248 node3.fio

3. 关于Fio生成的随机序列

虚拟机上Fio的随机读IOPS高到吓人,不太正常。已经有人深入源码分析了。结论是 伪随机序列。
文章连接

验证一下:

3.1. ESXi虚拟机:

  • 裸盘:

随机写后随机读

顺序写后随机读

  • 文件系统

3.2. 物理机

  • 裸盘
  • 文件系统

随机写后随机读

顺序写后随机读