FIO 之入门指南

一、概述

FIO 是一个开源的主流的 Linux 磁盘 IO 测试工具,可模拟各种 IO workload,广泛用于 benchmark、QA、验证等场景,支持多达19种 IO engines(如:libaio, sync等),并支持多种操作系统,如:Linux、Windows。通常对于磁盘的测试主要会关注这几个测试项,分别是:Iops,也就是每秒进行读写(I/O)操作的次数,它评估的是,每秒对于磁盘的操作次数和能力,执行次数越多说明执行数据越快。

另外一个指标就是对磁盘的吞吐率,它表示每秒对于磁盘的读写数据量,单位为 MB/s,数值越高表示读写数据越多。

第三个指标就是读写延迟,表示单个 IO 去写磁盘,做一次 IO 操作的耗时是多少。

我们使用 FIO 这个工具可以针对这三项指标去进行测试,并分析结论,在使用 FIO 之前建议你尽量使用一台空闲的机器来运行,以免因为 FIO 对操作系统上的磁盘或者文件的读写而损坏文件系统,这个地方你需要注意一下。


二、安装

有两种方式安装fio,binary 安装和 source 安装,本文使以Binary的方式安装。

2.1 下载rpm进行安装

从官网上下载Redhat系统所对应的3.1-1.el7版本。访问方式如下:

 https://github.com/axboe/fio -> https://apps.fedoraproject.org/packages/fio -> 3.1-1.el7

选择“fio-3.1-1.el7.x86_64.rpm”二进制软件包进行下载。

2.2 yum直接安装

另外也可以直接从yum方式进行安装,yum install fio

[root@CNSZ036811 ~]# fio -v

fio-3.1


三、基础概念

在讲解 fio 之前,有必要了解一些其中涉及到的基础概念。

IO 类型(IO pattern:指读写方式,顺序、随机两种。

大小:上层应用读写数据时的最小逻辑存储单元,如:4KB,1MB。磁盘性能测试过程,衡量 IOPS 时,通常采用小块数据随机读写(如:4K >= 块大小 <=32K 块大小),而衡量吞吐量时,通常采用大块数据顺序读写(如:64K >= 块大小 <= 1M)。

IO 大小:每次 IO 请求需要读写的数据大小。

IO 引擎:作业读写 IO 的方式,即以特定方式来访问存储文件。每种IO引擎有其自身的使用场景。

线程数:默认情况下是使用 fork 创建进程的方式来运行作业,但开销较大,因此通常情况,会指定 -thread 参数以线程方式测试。

队列深度:队列深度指系统中等待处理的 IO 请求的数目。队列深度的值决定了应用程序可以让多个 IO 操作排队供磁盘处理。


四、FIO 体验

了解了这些基本概念后,我们开始 fio 体验之旅。我们先来运行一个最简单的命令来感受一下 fio。

[root@cnsz036814 ~]# fio -filename=/dev/rbd0 -name=mytest

mytest: (g=0): rw=read, bs=(R) 4096B-4096B, (W) 4096B-4096B, (T) 4096B-4096B, ioengine=psync, iodepth=1

fio-3.1

Starting 1 process

Jobs: 1 (f=1): [f(1)][100.0%][r=273MiB/s,w=0KiB/s][r=69.9k,w=0 IOPS][eta 00m:00s]

mytest: (groupid=0, jobs=1): err= 0: pid=3367325: Thu Apr  4 14:30:31 2019

  read: IOPS=26.5k, BW=103MiB/s (108MB/s)(10.0GiB/99102msec)

    clat (nsec): min=1042, max=528258k, avg=37415.13, stdev=2331215.59

    lat (nsec): min=1087, max=528258k, avg=37464.12, stdev=2331215.58

    clat percentiles (nsec):

    |  1.00th=[    1160],  5.00th=[    1192], 10.00th=[    1208],

    | 20.00th=[    1240], 30.00th=[    1256], 40.00th=[    1304],

    | 50.00th=[    1368], 60.00th=[    1448], 70.00th=[    1496],

    | 80.00th=[    1592], 90.00th=[    1768], 95.00th=[    1992],

    | 99.00th=[    2576], 99.50th=[    3504], 99.90th=[    35584],

    | 99.95th=[  5406720], 99.99th=[119013376]

  bw (  KiB/s): min= 8192, max=1136744, per=99.01%, avg=104755.10, stdev=208227.89, samples=198

  iops        : min= 2048, max=284186, avg=26188.71, stdev=52057.00, samples=198

  lat (usec)  : 2=95.25%, 4=4.31%, 10=0.22%, 20=0.09%, 50=0.03%

  lat (usec)  : 100=0.01%, 250=0.01%, 500=0.01%, 750=0.01%, 1000=0.01%

  lat (msec)  : 2=0.03%, 4=0.01%, 10=0.01%, 20=0.01%, 50=0.01%

  lat (msec)  : 100=0.01%, 250=0.01%, 500=0.01%, 750=0.01%

  cpu          : usr=1.94%, sys=4.69%, ctx=2328, majf=0, minf=62

  IO depths    : 1=100.0%, 2=0.0%, 4=0.0%, 8=0.0%, 16=0.0%, 32=0.0%, >=64=0.0%

    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%

    issued rwt: total=2621440,0,0, short=0,0,0, dropped=0,0,0

    latency  : target=0, window=0, percentile=100.00%, depth=1

Run status group 0 (all jobs):

  READ: bw=103MiB/s (108MB/s), 103MiB/s-103MiB/s (108MB/s-108MB/s), io=10.0GiB (10.7GB), run=99102-99102msec

Disk stats (read/write):

  rbd0: ios=3741/0, merge=7487/0, ticks=428805/0, in_queue=428827, util=99.12%


在这个命令中,我们指定了一个非常简单的参数组合,仅包括被测 rbd 设备(/dev/rbd0),以及 job 的名字(mytest)两个参数,但是 fio 仍然能够正常运行,并输出测试结果,这两个参数组合是 fio 运行时所需要显式指定的最小参数组合。当然,fio 在运行时不止会使用这两个参数,其他未指定的但运行时所必要的参数,fio 会使用其默认值。

接下来,我们来了解一下输出的测试结果的含义,我会将其分为几个部分来讲解,若运行更为复杂的 fio 命令,输出也大同小异。

Part 1:

mytest: (g=0): rw=read, bs=(R) 4096B-4096B, (W) 4096B-4096B, (T) 4096B-4096B, ioengine=psync, iodepth=1

作业概况,含义如下:

mytest:指定的作业名字

g=0:该作业属于 group 0。

rw=read: 默认的 io pattern 是顺序读。

bs:分别表示用于 read/write/trim 的块大小,默认是4K。

ioengine=sync,默认 IO 引擎是psync。

iodepth=1:队列深度默认为1,表明设备上正在运行的 IO unit 数量不超过 1。


Part 2:

Jobs: 1 (f=1): [f(1)][100.0%][r=273MiB/s,w=0KiB/s][r=69.9k,w=0 IOPS][eta 00m:00s]

显示创建的job的状态,字段含义如下:

Jobs: 1:表示定义的作业,此处只定义了一个,也即进程数。

(f=1):表示当前打开的文件数量

[R(1)]:表示该作业当前状态,此处表示运行,顺序读

[100.0%]:表示该作业预估完成的百分比,此处表示 100% 结束。

接下来,显示了 IO 速率,分别指(读/写/trim)带宽和 IOPS,其中trim是可选项。


Part 3

mytest: (groupid=0, jobs=1): err= 0: pid=3367325: Thu Apr  4 14:30:31 2019

作业名字以及作业相关信息,比如:group id,作业数(jobs=1),作业完成时间。

err= 0:作业运行过程,no errors happened。


Part 4

read: IOPS=26.5k, BW=103MiB/s (108MB/s)(10.0GiB/99102msec)

    clat (nsec): min=1042, max=528258k, avg=37415.13, stdev=2331215.59

    lat (nsec): min=1087, max=528258k, avg=37464.12, stdev=2331215.58

    clat percentiles (nsec):

    |  1.00th=[    1160],  5.00th=[    1192], 10.00th=[    1208],

    | 20.00th=[    1240], 30.00th=[    1256], 40.00th=[    1304],

    | 50.00th=[    1368], 60.00th=[    1448], 70.00th=[    1496],

    | 80.00th=[    1592], 90.00th=[    1768], 95.00th=[    1992],

    | 99.00th=[    2576], 99.50th=[    3504], 99.90th=[    35584],

    | 99.95th=[  5406720], 99.99th=[119013376]

  bw (  KiB/s): min= 8192, max=1136744, per=99.01%, avg=104755.10, stdev=208227.89, samples=198

  iops        : min= 2048, max=284186, avg=26188.71, stdev=52057.00, samples=198

  lat (usec)  : 2=95.25%, 4=4.31%, 10=0.22%, 20=0.09%, 50=0.03%

  lat (usec)  : 100=0.01%, 250=0.01%, 500=0.01%, 750=0.01%, 1000=0.01%

  lat (msec)  : 2=0.03%, 4=0.01%, 10=0.01%, 20=0.01%, 50=0.01%

  lat (msec)  : 100=0.01%, 250=0.01%, 500=0.01%, 750=0.01%

作业的IO统计信息

IOPS=26.5k, BW=103MiB/s:IOPS、BW 性能指标值。

(10.0GiB/99102msec):总共读取的数据量(10G)以及消耗的时间(99102毫秒)。

接下来是 IO 延迟相关的信息:slat/clat/lat/clat percentiles。

slat (usec):提交延迟【微秒】,即“需要多久将IO提交到Kernel进行处理”,the time it took to submit the I/O to kernel for processing。

clat (usec):完成延迟,即IO提交到Kernel到IO完成返回之间的时间,the time that passes between submission to the kernel and when the IO is complete, not including submission latency。

lat (usec):lat is the best metric which represents the whole latency an application would expericen. The avg slat + avg clat =~ avg lat 。

clat percentiles:clat的分布统计数据,表示 clat “置信级”。

90.00th=[     1768]:表明 90% 的 IO 的平均 clat 是1768 nsec。

NOTES:其计算方式,所有 IO 结束后,按照每个 IO clat 的值从小到大依次排序,并分别计算出前1%的平均clat,如:1.00th=[     1160],百分比越大,clat的值也会随着增大。

bw/iops 的统计信息。

Bandwidth minimum, maximum, percentage of aggregate bandwidth received, average and standard deviation.

接下来就是:lat的统计分布数据,如下:

lat (usec)   : 2=95.25%, 4=4.31%, 10=0.22%, 20=0.09%, 50=0.03%

lat (usec)   : 100=0.01%, 250=0.01%, 500=0.01%, 750=0.01%, 1000=0.01%

lat (msec)   : 2=0.03%, 4=0.01%, 10=0.01%, 20=0.01%, 50=0.01%

lat (msec)   : 100=0.01%, 250=0.01%, 500=0.01%, 750=0.01%

如:2=95.25%,表明 95.25% 的 IO requests 完成的时延小于2 usec (微秒),4=4.31%,4.31% 的request 完成的时延在 2 微秒和 4 微秒之间 [2, 4),即大于等于 2 微秒,小于 4 微秒。


part 5

  cpu          : usr=1.94%, sys=4.69%, ctx=2328, majf=0, minf=62

CPU相关统计信息

ctx:运行过程中,上下文切换次数

majf/minf:major/minor page faults的数量


part 6

  IO depths    : 1=100.0%, 2=0.0%, 4=0.0%, 8=0.0%, 16=0.0%, 32=0.0%, >=64=0.0%

    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%

    issued rwt: total=2621440,0,0, short=0,0,0, dropped=0,0,0

    latency  : target=0, window=0, percentile=100.00%, depth=1

IO 队列深度的统计分布情况:

IO depths:Distribution of I/O depths over the job lifetime.  Each entry covers depths from that value, and up to those that are lower than the next entry… e.g., 16=covers depths from 16 to 31。

16=100.0%...”,表明job was able to always have 16 IO unit in flight agaist the device。

IO submit/complete: distribution of submit/complete. Each entry denotes that amount and below, until the previous entry. e.g., 16=100% means that we submitted anywhere between 9 to 16 I/Os per submit call... 

4=100%means that we submitted anywhere between 1 to 4 IOs per submit call.

IO issued:Number of read/write/trim requests issued, and number of short or drop read/write requests.

IO latency:Distribution of I/O completion latencies.  The numbers follow the same pattern as IO depths.


part 7:

Run status group 0 (all jobs):

  READ: bw=103MiB/s (108MB/s), 103MiB/s-103MiB/s (108MB/s-108MB/s), io=10.0GiB (10.7GB), run=99102-99102msec

group statistics

io=10.0GiB (10.7GB):读取的数据总量。

bw=103MiB/s (108MB/s):Aggregate bandwidth of all jobs/threads in the group。

103MiB/s-103MiB/s:Minimum/Maximum average bandwidth a thread saw.

run=99102-99102msec:mint/maxt   Shortest runtime of threads in the group.

NOTES:If we have more than one thread to run in a group, so we can see different values for mint/minimum and maxt/maximum,,, here they're same, because we just have one job.


Part 8:

Disk stats (read/write):

  rbd0: ios=3741/0, merge=7487/0, ticks=428805/0, in_queue=428827, util=99.12%

磁盘信息

ios=3741/0, 作业运行过程中读写的 IO 数量,3741 read IO and 0 write IO on /dev/rbd0

merge: Number of merges IO fromthe I/O scheduler,即在 IO request queue 中被IO电梯算法合并的IO数量。

ticks: Number of ticks we kept the disk busy. A sign that the device is saturated.

in_queue:Total time spent in the disk queue.(毫秒),指 在 IO request queue 中消耗的时间。

util: 磁盘的利用率。


五、总结

通过本章的学习,我们了解了 fio 安装,fio 基本使用方式,以及 fio 输出结果中各字段所代表的含义。在接下来的一系列文章,我们将探索 fio 更多特性,期望通过该系列文章,能够熟练掌握 fio 测试工具,最终更好地为我们的测试工作服务。

你可能感兴趣的:(FIO 之入门指南)