前言
最近项目组要调研一下Linux磁盘加密的技术,测试一下自研XTS模式算法的性能是否满足需求。
采用fio这个Linux下比较流行的磁盘IO性能工具来测试,浅浅地学习了一下fio的使用,所以就有了本文的小结。
fio最初是作者用来保存测试程序的,这些程序用于测试不同工作负载、定位性能问题或者重现bug。最后,作者就整了这么个工具,可以模拟各种IO负载,用于重复测试。
fio经过配置可以派生出许多进程或者线程用于处理用户指定类型的IO负载。fio定义了一些global参数,这些参数会被所有的进程或线程共享。进程或者线程也可以定义相同参数的值来覆盖global参数。fio可以读取一个job文件来根据配置进行处理。
fio支持运行于多种类型的操作系统上,一些特性或者选项只能运行于指定的操作系统。
编译安装
fio源码是开源的, 可以从github上下载后编译, 也可以直接使用apt安装。
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文件参数就可以运行了。
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一般包含如下参数:
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还有额外的参数设置。
测试场景
我测试时,使用的场景就比较简单。
包含随机读、随机写、顺序读、顺序写。
如果磁盘加密的话,读的时候会调用算法的解密操作,写的时候会调用算法的加密操作。
分别测试得到加密和不加密的性能数据,然后对比就可以得到加密前后的性能损耗比。
这个是我测试时使用的命令:
#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。
运行后的效果如图:
圈红的就是具体的性能。
测试准备
测试时需要使用独立了一个分区进行测试。我们使用fdisk创建一个50G的分区,所有测试都在同一个分区进行。 分区文件系统使用ext4。
测试加密时,需要用到linux的磁盘加密的模块dm-crypt。在用户态用对应的命令cryptsetup来调用。
这块篇幅比较大,单独开个文章讲。
行动,才不会被动!
欢迎关注个人公众号 微信 -> 搜索 -> fishmwei,沟通交流。
博客地址: fishmwei.github.io
掘金主页: juejin.cn/user/208432…