FIO Benchmark

一、简介

FIO为Linux kernel的IO部分维护者axobe开发,Github: https://github.com/axboe/fio。FIO的详细使用方法参见自带的HOWTO文件。
FIO一种IO系统的Benchmark和压力测试工具,可以模拟不同IO场景下的IO负载。最初axobe设计FIO是为了节省为特定负载设计专门测试程序、进行性能测试,以及debug的时间。写测试程序非常浪费时间,因为不同的测试负载的IO场景不同,他们都用自己的方式产生IO,故需要模拟这些IO负载,FIO需足够灵活。
FIO支持 13种不同的 I/O 引擎, 包括:sync, mmap, libaio, posixaio, SG v3, splice, null, network,syslet,guasi,solarisaio 等等。 FIO 的引擎能识别简单易懂的job file文本去进行测试,同时能提供各种 I/O 性能指标,如I/O 延迟、IOPS和带宽等。因此被大量的制造商和广泛的用户认可,作为确认IO系统良好的测试工具。

二、典型工作过程

FIO命令行格式:fio [options] [job options] <job file(s)>

1. 运行过程

1)确定待模拟IO负载的IO参数,如I/O type,Block size,I/O engine,I/O depth,Target file/device等。可以配合fio的一些命令行参数来涉及I/O参数。如--parse-only或--showcmd等。
2)写一个 job file来描述要simulate的 I/O 负载。一个 job 文件可以控制产生任意数目的线程和文件。典型的 job 文件有一个 global 段(定义共享参数),一个或多个job 段(描述具体要产生的 job)。
3)运行时,FIO 从文件读这些参数,做处理,并根据这些参数描述,启动这些simulate线程/进程。
4)测试完成后,输出测试结果。
5)对FIO测试结果进行分析,评估IO系统的设计或优化方案或确定debug思路。

2. 运行方式

按参数输入方式分为如下两种:
1) 命令行方式:如FIO –filename=/dev/sdb –direct=1 –rw=randread –bs=4k –size=60G –numjobs=64 –runtime=10 –group_reporting –name=test
2) fio job_file 方式:如job_file 的名字为 test,则运行方式为 fio test。
按FIO工作模式分为如下两种:
1)client/server方式:FIO工作模式可以分为前端和后端,即client端和server端。server端执行fio --server,client端执行fio --client=hostname jobfile,这样client端就可以把jobfile发到server端来执行,hostname为server端的IP。
2)本地执行:命令行/job file。

3. 命令行选项

FIO有很多有用的命令行选项,具体请直接查看fio --help或HOWTO文档。这里简单列出如下几个:
  • --parse-only:仅解析configuration文件的参数使用是否正确;
  • --output:结果输入到一个文件中;
  • --cmdhelp=cmd:打印某个命令的帮助文档;
  • --showcmd:解析配置文件并转化成命令行参数;

三、常用参数

1) IO type:表示 I/O 类型,Read Write;包括:Read 顺序读、 Write 顺序写、RandWrite 随机写、 RandRead 随机读。例如:rw=randwrite。
2) Block Size: 测试工具向被测设备发出的读写数据块的大小,可以是一个单独的值,也可以是一个范围。例如:blocksize=4k,4K 是主流,8K 是 Mysql和 Oracle,16K 是 MysqlInnodb。
3) IO engine: I/O 引擎,处理 IO 的方式,定义了发起 IO 的方式,可以是内存映射文件,可以是使用普通的读/写,我们可以使用 splice,异步 IO,syslet,甚至 SG(SCSI generic sg) 。包括 sync,pync,vsync,libaio 等,目前使用最广泛的是 libaio。
  • Sync:基本的read,write。通过lseek来作定位;
  • Psync:基本的pread,pwrite,在文件描述符给定的位置偏移上读取或写入数据,pread() 从文件 fd 指定的偏移 offset (相对文件开头) 上读取 count 个字节到buf 开始位置。文件当前位置偏移保持不变。 pwrite() 把缓存区 buf 开头的 count个字节写入文件描述符 fd offset 偏移位置上,文件偏移没有改变。 fd 引用的文件必须是可定位的,属于同步I/O;
  • Vsync:基本的 readv, writev;
  • Libaio: Linux 专有的异步 IO,Linux 仅支持非 buffered IO 的队列行为;
注意
  • 同步和异步的区别:同步 IO 是指,进程触发 IO 操作后,后面的操作不能进行,只能等待 IO 操作完成或者放弃 IO 操作,保证当前只有一个 IO 操作在进行。异步 IO 是指,触发 IO 操作以后,直接返回,可以继续执行后面的操作,IO 交给内核来处理,完成后内核通知进程 IO 完成。
  • libaio 引擎会用这个 iodepth 值来调用 io_setup,准备可以一次提交iodepth 个 IO 的上下文,同时申请iodepth个 io 请求队列用于保持 IO。在压测进行的时候,系统会生成特定的 IO 请求,往 io 请求队列里面提交,当队列里面的IO个数达到 iodepth_batch值的时候,就调用 io_submit 批次提交请求,然后开始调用 io_getevents 开始收割已经完成的 IO。每次收割多少呢?由于收割的时候,超时时间设置为 0,所以有多少已完成的 IO 就收割多少,最多可以收割 iodepth_batch_complete 个 IO。随着收割,IO 队列里面的 IO 数就少了,那么需要补充新的 IO。什么时候补充呢?当 IO 数目降到 iodepth_low 值的时候,就重新填充,保证 OS 可以看到至少 iodepth_low 数目的 io 在电梯口排队着。
  • libaio,这个是追求 IOPS 的;对于延时为主的测试,建议使用 psync。
4) IO size: 总共要读写的数据大小。例如:size=200G
5) IO depth:测试的队列深度,队列深度表示控制器可同时发送给被测设备的指令数目。在 ATA 指令集的 Read/Write FP DMA Queue 指令中,可以给每个读写指令带上标签。当队列深度为1时,控制器需要等待被测设备完成指令并返回结果后才可执行下一条指令;当队列深度大于 1 时,控制器可以向被测设备发出多条指令,并给每个指令附带一个标签作为指令号,此时被测设备并不按照指令号的顺序返回结果,从而可根据自身 Firmware 算法进行优化,寻找最容易得到的结果并反馈给控制器。当某一条指令的结果返回之后,该标签被回收并可再次利用。针对 SATA硬盘或 SSD,需要控制器工作在 AHCI 模式并且操作系统加载 AHCI 驱动程序且被测设备本身要支持 NCQ 才能支持此种访问模式。按照上述原理,在队列深度增加时,被测设备的访问效率将有明显提升,故性能也有相应提升。 默认对于每个文件来说是 1,可以设置一个更大的值来提高并发度。例如:iodepth=1
6) IO type:表示我们将执行 buffered io 还是 direct/raw io。 ZFS 和 Solaris 不支持direct io,在 windows 上同步 IO 引擎不支持 direct io。 Direct=0 时,则表明采用 buffered io。例如:direct=1
7) Num files: 表示负载将分发到几个文件中。例如:nrfiles=8
8) Num threads: 创建多少个进程/线程来并发执行。例如:numjobs=1。numjobs 建议等于 CPU 的 core 值,即 HT=off。
9) Runtime: 测试运行时间。例如:runtime=30
10)数据填充方式: 当进行数据写入时,可选择写入数据的形式。此选项可选三种模式,分别为重复填充、伪随机填充、随机填充。重复填充表示全 0 的数据写入,当 SSD主控支持数据压缩功能时,大量的全 0 数据将以压缩的方式写入 SSD 从而显著提高性能;伪随机填充写入即为伪随机数的填充写入,由于生成随机数需要花费大量时间,故在通常测试中,为减少等待时间,一般选择伪随机数填充。在选择伪随机数写入后,SSD 主控即使支持数据压缩功能也不能够对伪随机数进行压缩;全随机填充即为先进行随机数生成,之后再进行写入。随机数生成会消耗大量时间,通常测试中不采用此种模式。例如:refill_buffers
11) percentage_random:随机和顺序比率;例如:percentage_random=80,80%的随机。
12) time_based :决定脚本的运行时间,即使 file 已被完全读写或写完,也要执行完runtime 规定的时间。它是通过循环执行相同的负载来实现的。例如:time_based。
13) 目标盘符/被测盘符:当需要测试多个磁盘时,需要增加多行以下内容,例如: filename=/dev/sdb; 如果写在配置文件中,则需创建多个job区分多个不同的测试目标设备;

四、结果分析

1. slat:submission latency提交延迟,意思为“how long did it take to submit this IO to the kernel for processing?”;
2. clat:completion latency完成延迟,意思为“This is the time that passes between submission to the kernel and when the IO is complete, not including submission latency”;
3. clat percentiles:描述IO整体延迟latency distribution,为不同百分比IO的clat。可以根据这些百分比数来绘制图形,从整体上分析IO系统的IO延时。这是非常有用的一个用来描述IO系统延时情况的指标,例如可以比较TP99、TP90等性能指标。
4. IO depths:这个iodepth设置是用来控制在任意给定时刻,有多少个IO被提交给OS。这个参数完全是应用端来设置,与IO设备的IO queue不同。summit和complete表明fio一次提交多少个IO,或一次完成多少个IO。

Reference

1. FIO_HOWTO,见附件;

附件列表

     

    posted @ 2017-03-13 15:04  HiPhoenix  阅读(4459)  评论(0编辑  收藏  举报