0%

周谈(44)- fio工具使用

前言

最近项目组要调研一下Linux磁盘加密的技术,测试一下自研XTS模式算法的性能是否满足需求。

采用fio这个Linux下比较流行的磁盘IO性能工具来测试,浅浅地学习了一下fio的使用,所以就有了本文的小结。

fio最初是作者用来保存测试程序的,这些程序用于测试不同工作负载、定位性能问题或者重现bug。最后,作者就整了这么个工具,可以模拟各种IO负载,用于重复测试。

fio经过配置可以派生出许多进程或者线程用于处理用户指定类型的IO负载。fio定义了一些global参数,这些参数会被所有的进程或线程共享。进程或者线程也可以定义相同参数的值来覆盖global参数。fio可以读取一个job文件来根据配置进行处理。

fio支持运行于多种类型的操作系统上,一些特性或者选项只能运行于指定的操作系统。

编译安装

fio源码是开源的, 可以从github上下载后编译, 也可以直接使用apt安装。

1
2
3
4
5
6
7
8
9
10
git clone https://github.com/axboe/fio.git

./configure
make
make install


apt install fio

apt install libaio-dev # 如果要使用libaio引擎 需要安装libaio-dev, 这边的工作原理没有深入研究,默认采用libaio, aio的话之前有文章介绍过了,就是linux下的一种异步io机制。

fio运行命令

fio的运行命令比较简单,只需要给定一个或者job文件参数就可以运行了。

1
fio [options] [jobfile] ...

fio会根据job文件描述的参数进行处理。当出入多个job文件时,fio会串行的执行每个job文件。

如果一个job文件里只包含一个job,那么也可以通过命令行的方式执行这个job,命令行的参数等同于job文件内的参数。也可以使用命令行给定多个job的入口,每当fio遇到–name的选项后,就会从新开始一个job,名称就是name的值。name参数后面的值会被应用到该job上。

一般fio运行不需要root用户,除非指定的文件或者设备有权限要求。如果job文件用-替换,那么就会从标准输入读取job的参数。

fio的命令选项比较多,具体可以看源码中的HOWTO.rst文件。这里举例讲几个常用的job参数。

每个job一般包含如下参数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

I/O type
定义io模式。我们可能只是顺序读某些文件,或者随机写某些文件。或者同时进行读写,顺序或者随机的。定义从缓存读写还是直接读写。

Block size
定义读写I/O的粒度,可以是一个固定的值也可以是一个区间范围。测试的时候,这个值太小的话,会导致线程切换频繁,对结果影响很大。

I/O size
读写I/O的数据总量,一般设置为读写文件的大小。

I/O engine
如何定义IO,可以是内存映射文件,也可以是普通的读写,可以使用连续或者异步IO,甚至是SG(SCSI generic sg)。

I/O depth:
如果使用异步IO引擎,设置每个队列的深度,就是允许最多flight的IO数。

Target file/device:
指定多少个文件来分摊工作负载。

Threads, process and job synchronization:
指定线程或者进程数。

filename:
具体读写的文件或者设备路径

以上是基础的参数用来定义工作负载的,每个job还有额外的参数设置。

测试场景

我测试时,使用的场景就比较简单。

包含随机读、随机写、顺序读、顺序写。

如果磁盘加密的话,读的时候会调用算法的解密操作,写的时候会调用算法的加密操作。

分别测试得到加密和不加密的性能数据,然后对比就可以得到加密前后的性能损耗比。

这个是我测试时使用的命令:

1
2
3
4
5
6
7
8
9
10
11
12
13
14

#100%顺序写,写10G数据
fio -ioengine=libaio -bs=64k -direct=1 -thread -rw=write -filename=/mnt/sdb1/serial_write_test -name="BS 64KB serial write test" -iodepth=16 -cpumask=12 -size=10G

#100%随机写,写10G数据
fio -ioengine=libaio -bs=64k -direct=1 -thread -rw=randwrite -filename=/mnt/sdb1/rand_write_test -name="BS 64KB rand write test" -iodepth=16 -cpumask=12 -size=10G

# 100%随机读,使用前面随机写的数据,最多读60s
fio -ioengine=libaio -bs=64k -direct=1 -thread -rw=randread -filename=/mnt/sdb1/rand_write_test -name="BS 64KB random read test" -iodepth=16 -time_based -runtime=60 -cpumask=12 -size=10G


# 100%顺序读,使用前面顺序写的数据,最多读60s
fio -ioengine=libaio -bs=64k -direct=1 -thread -rw=read -filename=/mnt/sdb1/serial_write_test -name="BS 64KB serial read test" -iodepth=16 -time_based -runtime=60 -cpumask=12 -size=10G

IO方式使用libaio,linux支持的异步IO。块大小选择64k,direct=1不使用系统的文件缓存功能,thread 开启独立的线程处理, iodepth队列深度设置为16, time_based要求基于时间测试,time_based跟runtime组合使用,就是必须运行这么长的时间。cpumask选定执行IO的CPU核,size就是文件的大小为10G。

运行后的效果如图:

fio_result

圈红的就是具体的性能。

测试准备

测试时需要使用独立了一个分区进行测试。我们使用fdisk创建一个50G的分区,所有测试都在同一个分区进行。
分区文件系统使用ext4。

测试加密时,需要用到linux的磁盘加密的模块dm-crypt。在用户态用对应的命令cryptsetup来调用。

这块篇幅比较大,单独开个文章讲。


行动,才不会被动!

欢迎关注个人公众号 微信 -> 搜索 -> fishmwei,沟通交流。

博客地址: https://fishmwei.github.io

掘金主页: https://juejin.cn/user/2084329776486919