FIO性能测试

FIO 有众多参数,如果你尚不熟悉这款测试工具,我们总结了最为关键的一系列参数的用法,帮助你自行构造测试。

说明
name测试任务名称。
directory测试数据读写路径,即 JuiceFS 挂载点,以下测试以 /jfs 举例。
readwriterw读写模式,在针对 JuiceFS 的测试中,一般只需要使用 readwriterandread 以及 randwrite 这四种模式来分别测试顺序读、顺序写、随机读以及随机写的性能。
blocksizebs每次读写的块数据大小,测试顺序读写场景时设为 1m 或 4m,随机读写场景可以取值 4k~256k,或者结合实际应用场景来设置。
numjobs并发度,默认每个任务(job)是一个独立的 fork thread,如果不进行特殊设置,那么多个 job 会各自分批读写文件,不会出现多个 job 读写同一文件的情况,这也是我们推荐的测试设置。
openfiles如无特殊要求(比如使用 time_based 模式),建议携带 --openfiles=1 参数,让每个线程同一时刻只打开和处理 1 个文件。如果按照 FIO 的默认行为,他会打开 nrfiles 个文件,因此文件量增大,JuiceFS 的缓冲区会迅速被挤占、严重影响性能。除非明确要测同时打开多个文件、反复读取他们的时候,否则默认都是单线程内串行处理。
filename_format一般避免使用该参数。FIO 实际上不支持多个任务并发读取同一批文件,如果使用 filename_format 参数,会产生单线程、无并发的串行读效果,因此必须调整测试用例、改为每个 job 读取自己专属的一批文件。
filename一般避免使用该参数。比如在顺序写测试中用该参数规定了写入文件名,会造成 FIO 多线程写入同一文件,造成 FUSE 写流量远大于对象存储 PUT 的情况。
size每个任务处理的文件的总大小。
nrfiles在每个任务中生成的文件数量。
filesize每个任务中生成的单个文件大小,满足 filesize * nrfiles = size,因此该参数不需要和 size 同时设置。
direct文件读取过后,内核会利用空闲内存对数据、元数据进行缓存,因此往往只有首次读取产生了 FUSE 请求,后续的都通过内核返回了。因此如果没有特殊要求,建议所有测试都应携带 --direct=1 绕过内核页缓存,专注测试 FUSE 挂载点的能力。但如果希望尽可能贴近实际场景、充分利用空闲内存提升 I/O,此时可以去掉 --direct=1 来利用内核缓存。
ioengine如无特殊要求都应采用默认的 ioengine=psync。如果实际环境要运行的应用对接了 aio,那么不仅需要在 FIO 启用 ioengine=libaio,JuiceFS 挂载点也需要追加 -o async_dio 参数来进行适配。
refill_buffers默认情况下,FIO 会在测试任务开始时创建用于生成测试文件的数据片段,并一直重用这些数据。使用这个参数后,会在每次 I/O 提交后重新生成数据,保证生成测试文件内容有充分的随机性。
end_fsync对于 JuiceFS,write 成功以后只是将数据提交到读写缓冲区,并不代表数据就上传到对象存储了,需要 close 或者 fsync 才能触发持久化。因此对于写测试,建议开启该参数,以准确反映 JuiceFS 的性能。
file_service_type用来定义测试任务中的文件选取方式,有 randomroundrobinsequential 三种。在本章某些测试用例中使用了 file_service_type=sequential 来保证测试任务及时关闭文件、触发 JuiceFS 将写入数据持久化,在这点上使用 end_fsync 更合适。

构造测试

本小节提供一系列 FIO 命令示范,帮助你按照自己的实际环境构造测试。

如果测试集中的文件可以读写复用,那么建议先安排写测试,生成的文件正好可以用于后续的读测试。

顺序写测试:

# 顺序写 1 个大文件
fio --name=big-write --directory=/mnt/fio --group_reporting \
  --rw=write \
  --direct=1 \
  --bs=4m \
  --end_fsync=1 \
  --numjobs=1 \
  --nrfiles=1 \
  --size=1G

# 并发顺序写 1 个大文件,因此 16 线程一共写 16 个大文件
fio --name=big-write --directory=/mnt/fio --group_reporting \
  --rw=write \
  --direct=1 \
  --bs=4m \
  --end_fsync=1 \
  --numjobs=16 \
  --nrfiles=1 \
  --size=1G

# 并发顺序写多个大文件,并发度 16,每个线程写入 64 个大文件
fio --name=big-write --directory=/mnt/fio --group_reporting \
  --rw=write \
  --direct=1 \
  --bs=4m \
  --end_fsync=1 \
  --numjobs=16 \
  --nrfiles=64 \
  --size=1G

顺序读测试:

# 测试之前根据需要,可以选择清空本地数据缓存,以及内核缓存
rm -rf /var/jfsCache/*/raw
sysctl -w vm.drop_caches=3

# 顺序读 1 个大文件
fio --name=big-read-single --directory=/jfs/fio --group_reporting \
  --rw=read \
  --direct=1 \
  --bs=4m \
  --numjobs=1 \
  --nrfiles=1 \
  --size=1G

# 顺序读多个大文件
fio --name=big-read-multiple --directory=/jfs/fio --group_reporting \
  --rw=read \
  --direct=1 \
  --bs=4m \
  --numjobs=1 \
  --nrfiles=64 \
  --size=1G

# 并发顺序读多个大文件,线程数 64,每个线程读 64 个文件
fio --name=big-read-multiple-concurrent --group_reporting \
  --directory=/jfs/fio \
  --rw=read \
  --direct=1 \
  --bs=4m \
  --numjobs=64 \
  --nrfiles=64 \
  --openfiles=1 \
  --size=1G

如果你的场景需要构造随机读写测试,也可以参考上方的测试命令,需要修改的只有以下参数:

  • 使用 rw=[randread|randwrite] 来代表随机读和随机写;
  • 将 bs 按需设置为 4k~128k,或按照真实业务场景的写入大小来设定。

顺序写

对应的 FIO 配置:

sequential-write.fio

[global]
stonewall
group_reporting
openfiles=1
end_fsync=1
ioengine=sync
rw=write
bs=4M
filesize=1G
directory=/jfs/fio-dir

顺序读

sequential-read.fio

[global]
stonewall
group_reporting
openfiles=1
end_fsync=1
ioengine=sync
rw=read
bs=4M
filesize=1G
directory=/jfs/fio-dir

随机写

random-write.fio

[global]
stonewall
group_reporting
openfiles=1
end_fsync=1
ioengine=sync
rw=write
bs=4M
filesize=1G
directory=/jfs/fio-dir

大文件

在日志收集、数据备份、大数据分析等很多场景中,都需要做大文件顺序读写,这也是 JuiceFS 适用的典型场景。

注意:此处需要事先创建不同块大小的 JuiceFS 文件系统并进行挂载,在测试脚本中对 --directory 参数换成对应的 JuiceFS 挂载点。

大文件顺序读
fio --name=big-file-sequential-read \
    --directory=/jfs \
    --rw=read --refill_buffers \
    --bs=256k --size=4G
大文件顺序写
fio --name=big-file-sequential-write \
    --directory=/jfs \
    --rw=write --refill_buffers \
    --bs=256k --size=4G
大文件并发读
fio --name=big-file-multi-read \
--directory=/jfs \
--rw=read --refill_buffers \
--bs=256k --size=4G \
--numjobs={1, 2, 4, 8, 16}
大文件并发写
fio --name=big-file-multi-write \
    --directory=/jfs \
    --rw=write --refill_buffers \
    --bs=256k --size=4G  \
    --numjobs={1, 2, 4, 8, 16}
大文件随机读
fio --name=big-file-rand-read \
    --directory=/jfs \
    --rw=randread --refill_buffers \
    --size=4G --filename=randread.bin \
    --bs={4k, 16k, 64k, 256k} --pre_read=1

sync && echo 3 > /proc/sys/vm/drop_caches

fio --name=big-file-rand-read \
    --directory=/jfs \
    --rw=randread --refill_buffers \
    --size=4G --filename=randread.bin \
    --bs={4k, 16k, 64k, 256k}

为了精准地测试大文件随机读的性能,在这里我们先使用 fio 将文件预读取一遍,然后清除内核缓存(sysctl -w vm.drop_caches=3),接着使用 fio 进行随机读的性能测试。

在大文件随机读的场景,为了获得更好的性能,建议将挂载参数的缓存大小设置为大于将要读取的文件大小。

大文件随机写
fio --name=big-file-random-write \
    --directory=/jfs \
    --rw=randwrite --refill_buffers \
    --size=4G --bs={4k, 16k, 64k, 256k}

小文件

小文件读
fio --name=small-file-seq-read \
    --directory=/jfs \
    --rw=read --file_service_type=sequential \
    --bs={file_size} --filesize={file_size} --nrfiles=1000
小文件写

在默认的 fio 测试行为中会把文件的关闭操作留在任务最后执行,这样在分布式文件系统中存在因网络异常等因素丢失数据的可能。所以我们在 fio 的测试参数中使用了 --file_service_type=sequential 参数,这样 fio 会在测试任务中保证写完一个文件(执行 flush & close,把数据全部写入对象存储)再进行下一个文件。

fio --name=small-file-seq-write \
    --directory=/jfs \
    --rw=write --file_service_type=sequential \
    --bs={file_size} --filesize={file_size} --nrfiles=1000
小文件并发读
fio --name=small-file-multi-read \
    --directory=/jfs \
    --rw=read --file_service_type=sequential \
    --bs=4k --filesize=4k --nrfiles=1000 \
    --numjobs={1, 2, 4, 8, 16}
小文件并发写
fio --name=small-file-multi-write \
    --directory=/jfs \
    --rw=write --file_service_type=sequential \
    --bs=4k --filesize=4k --nrfiles=1000 \
    --numjobs={1, 2, 4, 8, 16}

文档内容来源:FIO 性能测试 | JuiceFS Document Center

如何在Linux实例中使用FIO工具测试块存储性能_云服务器 ECS(ECS)-阿里云帮助中心

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值