使用fio进行I/O性能测试

fio是一个非常灵活的I/O测试工具,支持多线程或进程模拟等I/O操作来进行压力测试,project官网为fio
(1). 安装fio首先要安装异步的I/O支持libaio.x86_64(Linux-native asynchronous I/O access library):
yum install libaio libaio-devel
应用使用IO通常有二种方式:同步和异步。 同步的IO一次只能发出一个IO请求,等待内核完成才返回,这样对于单个线程iodepth总是小于1,但是可以透过多个线程并发执行来解决,通常我们会用16-32根线程同时工作把iodepth塞满。 异步的话就是用类似libaio这样的linux native aio一次提交一批,然后等待一批的完成,减少交互的次数,会更有效率。(摘自参考2)
(2). 下载fio源代码并编译安装:

(3). fio支持的I/O引擎(摘自参考2)
fio中可以用-ioengine使用下面I/O引擎。

其中psync是常用的I/O engine,相比sync(read, write)和vsync区别在于:

常见的I/O测试模式如下(man fio)

对于混合I/O的读写,默认比例是50/50。 可以设置rwmixwrite=30指定比例为70/30
(4). fio的命令行参数
name 运行的job名。例如–name=randread01。

测试过程绕过机器自带的buffer。使测试结果更真实。
direct 测试过程跳过系统buffer,默认为direct=false。
filename=/var/data01/test_io 测试过程使用的文件,一般指向一个不存在的文件,fio会以随机的数据生成这个文件。也可以直接指向块设备文件。
bs 每次I/O操作的块大小,默认为bs=4K。
bsrange 同上,每次提交的block size,例如bsrange=4k-16k
runtime =300 测试时间(秒)
numjobs =8 并发执行的线程数
group_reporting 显示进程汇总结果
zero_buffer 用0初始化系统buffer
lockmem=4g 限定使用4g的内存进行测试
……
和异步I/O相关的几个参数:
iodepth_batch=4 Number of I/Os to submit at once. Default: iodepth.
iodepth_batch_complete=int This defines how many pieces of IO to retrieve at once. It defaults to 1 which means that we’ll ask for a minimum of 1 IO in the retrieval process from the kernel. The IO retrieval will go on until we hit the limit set by iodepth_low. If this variable is set to 0, then fio will always check for completed events before queuing more IO. This helps reduce IO latency, at the cost of more retrieval system calls.
iodepth_low=int Low watermark indicating when to start filling the queue again. Default: iodepth.
iodepth=4 Number of I/O units to keep in flight against the file.
libaio 等异步IO engine中,会调用io_setup准备可以一次提交iodepth个IO的上下文,同时申请个io请求队列用于保持IO。 在压测进行的时候,系统会生成特定的IO请求,往io请求队列里面扔,当队列里面的IO个数达到iodepth_batch值的时候,就调用io_submit批次提交请求,然后开始调用io_getevents开始收割已经完成的IO。 每次收割多少呢?由于收割的时候,超时时间设置为0,所以有多少已完成就算多少,最多可以收割iodepth_batch_complete值个。随着收割,IO队列里面的IO数就少了,那么需要补充新的IO。 什么时候补充呢?当IO数目降到iodepth_low值的时候,就重新填充,保证OS可以看到至少iodepth_low数目的io在电梯口排队着。(摘自参考3)
(5). 几种模式测试
测试机disk是一个普通三星SSD磁盘,将其挂到了/var/data01这个目录下。

这次测试IOPS 36.1K,144.4MB/s。iostat结果中,avgrq-sz(The average size in sectors of the requests that were issued to the device)和avgqu-sz(The average queue length of the requests that were issued to the device)都有较高的值。
b). random read of psync, with 16k blocksize and 8 threads, rumtime=120

提高块的大小,IOPS下降了一些,而读取速率高出了1.5倍。由此可见在数据库应用中,大blocksize能显著提高读I/O的性能。
c). random write of libio, with 16k blocksize, 4 threads and iodepth=4, rumtime=60

我这个普通SSD设备,写的性能远远小于读的性能。126.3MB/3 & 8080 IOPS
d). random read & write(8:2) of libio, with 16k blocksize, 4 threads and iodepth=8, rumtime=60

好吧,结果更加惨不忍睹。而且I/O有很高队列长度,并且出现了3ms的I/O等待。

^^
参考:
Linux manual
Fio IO性能测试工具介绍 http://blog.yufeng.info/archives/677
io系统的压力测试工具-fio http://blog.csdn.net/wyzxg/article/details/7454072

Posted in Ops, Tools.
  1. 这个测试非常不严谨应该指定 测试文件而不是设备名, 博主非常糊涂之人

  2. 网上写FIO的,都是抄来抄去,真没见过几个靠谱的。包括褚霸大神的那篇,底下点评一个网友的测试结果,为什么iostat结果和fio结果差了一倍,霸爷说是因为条带的关系,我测试出来一看,是计算单位的原因啊,一个是簇512字节,一个是1K单位啊。