参考:
http://blog.csdn.net/xiaowei7hao/article/details/44176021
http://blog.csdn.net/youngstonep/article/details/52315192
介绍
FIO是测试IOPS的非常好的工具,用来对 硬件进行压力测试和验证。
fio 官网地址:http://freecode.com/projects/fio
安装
- 下载
- 解压
- 安装
- 相关命令:
tar -zxvf fio-2.0.7.tar.gz
cd fio-2.0.7
make
make install
使用
1.随机写测试
fio -filename=/dev/sdb1 -direct=1 -iodepth 1 -thread -rw=randwrite -ioengine=psync -bs=16k -size=200G -numjobs=30 -runtime=1000 -group_reporting -name=mytest
2.随机读测试
fio -filename=/dev/sdb1 -direct=1 -iodepth 1 -thread -rw=randread -ioengine=psync -bs=16k -size=200G -numjobs=10 -runtime=1000 -group_reporting -name=mytest
3.顺序写测试
fio -filename=/dev/sdb1 -direct=1 -iodepth 1 -thread -rw=write -ioengine=psync -bs=16k -size=200G -numjobs=30 -runtime=1000 -group_reporting -name=mytest
4.顺序读测试
fio -filename=/dev/sdb1 -direct=1 -iodepth 1 -thread -rw=read -ioengine=psync -bs=16k -size=200G -numjobs=30 -runtime=1000 -group_reporting -name=mytest
5.混合随机读写测试
fio -filename=/dev/sdb1 -direct=1 -iodepth 1 -thread -rw=randrw -rwmixread=70 -ioengine=psync -bs=16k -size=200G -numjobs=30 -runtime=100 -group_reporting -name=mytest -ioscheduler=noop
命令说明
fio -filename=<测试文件或块设备> -ioengine=sync -direct=1 -rw=randread -bs=8k -size=1G -numjobs=8 -runtime=10 -group_reporting -name=fio_test
- -filename
filename=/dev/sdb1 测试文件名称,通常选择需要测试的盘的data目录。 - -ioengine
io引擎使用pync方式
sync:采用read,write,使用fseek定位读写位置。
psync:采用pread、pwrite进行文件读写操作
vsync:采用readv(2) orwritev(2)进行文件读写操作
pread()
ssize_t pread (int filedes, void *buf, size_t nbytes, off_t offset );
成功:返回读到的字节数;出错:返回-1;到文件结尾:返回0
原因:由于lseek和read 调用之间,内核可能会临时挂起进程,所以对同步问题造成了问题,调用pread相当于顺序调用了lseek和read,这两个操作相当于一个捆绑的原子操作。
实现:文件(由filedes所指)-读nbytes字节->内存buf中。
补充:调用pread时,无法中断其定位和读操作,另外不更新文件指针
pwrite()
ssize_t pwrite (int filedes, const void *buf, size_t nbytes, off_t offset );
成功:返回已写的字节数;出错:返回-1;
原因:由于lseek和write 调用之间,内核可能会临时挂起进程,所以对同步问题造成了问题,调用pwrite相当于顺序调用了lseek和 write,这两个操作相当于一个捆绑的原子操作。
实现:文件(由filedes所指)<-写nbytes字节-内存buf中。
补充:调用pwrite时,无法中断其定位和读操作,另外不更新文件指针。
readv()
ssize_t readv(int filedes,const struct iovec*iov,int iovcnt);
writev()
ssize_t writev(int filedes,const struct iovec*iov,int iovcnt);
参数:
filedes 文件描述符
iov 指向iovec结构数组的一个指针。
iovcnt 数组元素的个数
返回值: 若成功则返回已读、写的字节数,若出错则返回-1 readv和writev函数用于
在一次函数调用中读、写多个非连续缓冲区。有时也将这两个函数成为散布读和聚集写。
这两个函数的第二个参数是指向iovec结构数组的一个指针:
struct iovec{
void *iov_base;
size_t iov_len;
};
writev以顺序iov[0]至iov[iovcnt-1]从缓冲区中聚集输出数据。writev返回输出的字节总数,通常,它应等于所有缓冲区长度之和。
readv则将读入的数据按上述同样顺序散布读到缓冲区中。readv总是先填满一个缓冲区,然后再填写下一个。readv返回读到的总字节数。如果遇到文件结尾,已无数据可读,则返回0。
参考:
http://blog.csdn.net/bruce0532/article/details/8936293
- -direct =1
测试过程绕过机器自带的buffer。使测试结果更真实 -rw(读写模式)=randwrite randread read write
读写模式
read:顺序读测试,使用方式-rw=read
write:顺序写测试,使用方式-rw=write
randread:随机读测试,使用方式-rw=randread
randwrite:随机写测试,使用方式-rw=randwrite
randrw:随机读写,-rw=randrw;默认比率为5:5,通过参数-rwmixread设定读的比率,如-rw=randrw-rwmixread=70,说明读写比率为70:30。或rwmixwrite- -bs 单次io的块文件大小为16k 。
- -size 本次的测试文件大小为
- -iodepth IO队列深入,即一次下发的IO的个数,例如:-iodepth=16
- -runtime =测试时间
- -group_reporting 关于显示结果的,汇总每个进程的信息。
- -numjobs : 本次的测试线程数
结果说明
解释
(对应值的数据说明不准)
1. mytest: (g=0): rw=read, bs=8K-8K/8K-8K/8K-8K, ioengine=sync, iodepth=1
当前测试为随机读(randread),IO块大小,文件读写方式psync,IO队列深度为1。
fio-2.1.10 :版本号
Starting 8 threads:开始read : io=8192.0MB, bw=11409MB/s, iops=1460.5K, runt= 718msec
fio做了10GB的IO,速率63.317MB/s,总IOPS 15829 (默认4k block size),运行了2分钟45秒。slat (usec): min=3, max=335, avg= 9.73, stdev= 5.76 代表“盘需要多久将IO提交到kernel做处理?”
clat (usec): min=1, max=32005, avg= 4.43, stdev=172.35 这是命令提交到kernel到IO做完之间的时间,不包括submission latency。在老版本的fio中,这是估计应用级延迟的最好指标。
clat percentiles (usec):
| 1.00th=[ 2], 5.00th=[ 2], 10.00th=[ 2], 20.00th=[ 2],
| 30.00th=[ 2], 40.00th=[ 2], 50.00th=[ 2], 60.00th=[ 2],
| 70.00th=[ 3], 80.00th=[ 3], 90.00th=[ 3], 95.00th=[ 3],
| 99.00th=[ 7], 99.50th=[ 11], 99.90th=[ 12], 99.95th=[ 13],
bw (MB /s): min= 917, max= 1898, per=12.29%, avg=1402.50, stdev=308.20
这是一组数据。与三行使用一样的单位不同,第三行使用了毫秒(ms),使得文本宽度可控。把第三行读成2000, 4000, 10000, 20000微秒(us)就更清晰了。
这组数据表示latency的分布,说明了51.41%的request延迟小于50微秒,48.53%的延迟小于100微秒(但是大于50微秒),以此类推。
bw 带宽(bandwidth)的意思显而易见, per :文档上说这个值是指在单个盘上跑多个负载,可以用来看每个进程消耗了多少IOlat (usec): min=1, max=32005, avg= 4.52, stdev=174.66 :似乎这个值是从IO结构体创建时刻开始,直到紧接着clat完成
cpu : usr=9.17%, sys=44.34%, ctx=419, majf=0, minf=16
这是用户/系统CPU占用率,进程上下文切换(context switch)次数,主要和次要(major and minor)页面错误数量(page faults)。由于测试是配置成使用直接IO,page faults数量应该极少IO depths : 1=100.0%, 2=0.0%, 4=0.0%, 8=0.0%, 16=0.0%, 32=0.0%, >=64=0.0%
Fio有一个iodepth设置,用来控制同一时刻发送给OS多少个IO。这完全是纯应用层面的行为,和盘的IO queue不是一回事。这里iodepth设成1,所以IO depth在全部时间都是1。submit : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
complete : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
submit和complete代表同一时间段内fio发送上去和已完成的IO数量。对于产生这个输出的垃圾回收测试用例来说,iodepth是默认值1,所以100%的IO在同一时刻发送1次,放在1-4栏位里。通常来说,只有iodepth大于1才需要关注这一部分数据。issued : total=r=1048576/w=0/d=0, short=r=0/w=0/d=0 :发送的IO数量
latency : target=0, window=0, percentile=100.00%, depth=1
Fio可以配置一个延迟目标值,这个值可以调节吞吐量直到达到预设的延迟目标。我还没有太多深入了解这部分。在基于时间或和容量的测试中,这行通常看起来一样。四个值分别代表预设的latency_target, latency_window, latency_percentile和iodepth。Run status group 0 (all jobs):
READ: io=8192.0MB, aggrb=11409MB/s, minb=11409MB/s, maxb=11409MB/s, mint=718msec, maxt=718msecDisk stats (read/write):
dfa: ios=944164/0, merge=0/0, ticks=812/0, in_queue=856, util=67.73%
最后,汇总输出吞吐量和时间。io=表示总共完成的IO数量。在基于时间的测试中这是一个变量,在基于容量的测试中,这个值能匹配size参数。aggrb是所有进程/设备的汇总带宽。minb/maxb表示测量到的最小/最大带宽。mint/maxt表示测试的最短和最长耗时。和io=参数类似,时间值对于基于时间的测试应该能匹配runtime参数,对于基于容量的测试是一个变量。