磁盘IO压测工具之fio命令(磁盘性能测试)
简介
目前主流的第三方IO测试工具有fio、iometer 和 Orion,这三种工具各有千秋,在linux 下也可以使用dd 进行简单的磁盘(文件系统)测试。fio在Linux系统下使用比较方便,iometer在window系统下使用比较方便,Orion是oracle的IO测试软件,可在没有安装oracle数据库的情况下模拟oracle数据库场景的读写。
FIO是一款开源的 I/O 压力测试工具,主要是用来测试磁盘的IO性能。它可以支持多种不同的I/O引擎。
fio 官网地址:http://freshmeat.net/projects/fio/
fio文档:https://fio.readthedocs.io/en/latest/index.html
FIO 是一个 I/O 工具,旨在用于基准测试和压力/硬件验证。它支持 19 种不同类型的 I/O 引擎(sync、mmap、libaio、posixaio、SG v3、splice、null、network、syslet、guasi、solarisaio 等)、I/O 优先级(适用于较新的 Linux 内核) 、评估 I/O、分叉或线程作业等等。它可以在块设备和文件上工作。fio 接受简单易懂的文本格式的职位描述。包括几个示例作业文件。
fio 显示各种 I/O 性能信息,包括完整的 IO 延迟和百分位数。Fio 在许多地方被广泛使用,用于基准测试、QA 和验证目的。它支持 Linux、FreeBSD、NetBSD、OpenBSD、OS X、OpenSolaris、AIX、HP-UX、Android 和 Windows。
Multithreaded IO generation tool , FIO 是一个多线程io生成工具,可以生成多种IO模式,用来测试磁盘设备的性能(也包含文件系统:如针对网络文件系统 NFS 的IO测试)。
安装
yum安装
下载:https://pkgs.org/download/fio
1 | yum install -y fio |
编译安装
下载:https://git.kernel.dk/cgit/fio/refs/
1 2 3 4 5 | wget https://git.kernel.dk/cgit/fio/snapshot/fio-3.33.tar.gz --no-check-certificate tar -xvf fio-3.33.tar.gz cd fio-3.33 ./configure --prefix=/usr/local/fio3.33 make && make install |
注意如果编译的时候出现gcc 版本过低,可参考问题升级gcc 后在编译。 或者安装fio-3.20的版本,如下:
12345678910111213 [root@test fio-3.33]# ./configure --prefix=/usr/local/fio3.33Operating system LinuxCPU x86_64Big endian noCompiler gccCross compile noStatic build noYour compiler doesn't support C11 atomics. gcc 4.9/clang 3.6 are theminimum versions with it - perhaps your compiler is too old?C11 atomics support not foundConfigure failed, check config.log and/or the above output
使用
fio支持的读写模式包括顺序读,随机读,顺序写,随机写,混合随机读写,混合顺序读写,真实的磁盘读取往往是随机IO。常用参数包括引擎,队列深度,线程,block,是否裸设备,读写方式,大小/耗时,跳过缓存等。
以下是对这些参数的简单介绍:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | filename=/dev/sdc 支持文件系统或者裸设备,压测多个磁盘 --filename=/dev/sda:/dev/sdb direct=1 测试过程绕过机器自带的buffer,使测试结果更真实 rw=randwread 测试随机读的I/O rw=randwrite 测试随机写的I/O rw=randrw 测试随机混合写和读的I/O rw=read 测试顺序读的I/O rw=write 测试顺序写的I/O rw=rw 测试顺序混合写和读的I/O bs=4k 单次io的块文件大小为4k bsrange=512-2048 同上,指定定数据块的大小范围 size=50g 本次的测试文件大小为50g,以每次4k的io进行测试 numjobs=30 本次的测试线程为30 runtime=1000 测试时间为1000秒,如果不写则一直将5g文件分4k每次写完为止 ioengine=psync io引擎使用pync方式,如果要使用libaio引擎,需要yum install libaio-devel包 rwmixwrite=30 在混合读写的模式下,写占30% group_reporting 关于显示结果的,汇总每个进程的信息 此外其他参数 lockmem=1g 只使用1g内存进行测试 zero_buffers 用0初始化系统buffer nrfiles=8 每个进程生成文件的数量 |
在 fio 中,iodepth
是指每个线程在执行 IO 操作时,可以同时发起的请求数量。更具体地说,iodepth
参数定义了一个线程可以保持处于挂起状态(即等待 I/O 完成)的 I/O 请求数量。
例如,如果 iodepth=4
,则每个线程可以同时保持 4 个 I/O 请求处于挂起状态,而不必等待先前的 I/O 操作完成。这样可以提高系统吞吐量和并发性,因为 I/O 操作可以同时在多个请求之间分配。
值得注意的是,iodepth
参数的最优值取决于应用程序的特定工作负载和硬件环境。一般来说,较大的 iodepth
值可以在具有更高 IOPS(每秒 I/O 操作数)和低延迟的高速硬件上实现更好的性能,而较小的 iodepth
值适用于低速硬件和较高的延迟要求。
执行多次测试的时候 ,由于命令行参数过多影响,不太直观,可以将参数写到配置文件中,把全局变量和测试变化的参数写在不同的块里,最后运行即可,比如我们要测试多个rw场景 write,readwrite ,可以写配置文件 fio_yace.cfg
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | [global] filename=/dev/vdb direct=1 iodepth=128 thread ioengine=libaio numjobs=30 size=10g runtime=600 group_reporting bs=4k [4k-write] rw=write stonewall [4k-randwrite] rw=randwrite stonewall |
注意,如果 [4k-write] 和 [4k-randwrite] 两个测试需要串行执行,需要在各自的块下面加上 stonewall 。
最后命令行运行
fio fio_yace.cfg
即执行测试。测试结果的数据较多,主要观察吞吐量和IOPS两个。当然延迟也需要进行观察。
示例
这里举几个例子供大家参考:
顺序读:
1 2 | fio -filename=/var/test.file -direct=1 -iodepth 1 -thread -rw=read -ioengine=psync \ -bs=16k -size=2G -numjobs=10 -runtime=60 -group_reporting -name=test_r |
随机写:
1 2 | fio -filename=/var/test.file -direct=1 -iodepth 1 -thread -rw=randwrite -ioengine=psync \ -bs=16k -size=2G -numjobs=10 -runtime=60 -group_reporting -name=test_randw |
顺序写:
1 2 | fio -filename=/var/test.file -direct=1 -iodepth 1 -thread -rw=write -ioengine=psync \ -bs=16k -size=2G -numjobs=10 -runtime=60 -group_reporting -name=test_w |
混合随机读写:
1 2 | fio -filename=/var/test.file -direct=1 -iodepth 1 -thread -rw=randrw -rwmixread=70 -ioengine=psync \ -bs=16k -size=2G -numjobs=10 -runtime=60 -group_reporting -name=test_r_w -ioscheduler=noop |
测试场景:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | -- 100%随机,100%读, 4K fio -filename=/dev/emcpowerb -direct=1 -iodepth 1 -thread -rw=randread -ioengine=psync -bs=4k -size=1000G -numjobs=50 -runtime=180 -group_reporting -name=rand_100read_4k -- 100%随机,100%写, 4K fio -filename=/dev/emcpowerb -direct=1 -iodepth 1 -thread -rw=randwrite -ioengine=psync -bs=4k -size=1000G -numjobs=50 -runtime=180 -group_reporting -name=rand_100write_4k -- 100%顺序,100%读 ,4K fio -filename=/dev/emcpowerb -direct=1 -iodepth 1 -thread -rw=read -ioengine=psync -bs=4k -size=1000G -numjobs=50 -runtime=180 -group_reporting -name=sqe_100read_4k -- 100%顺序,100%写 ,4K fio -filename=/dev/emcpowerb -direct=1 -iodepth 1 -thread -rw=write -ioengine=psync -bs=4k -size=1000G -numjobs=50 -runtime=180 -group_reporting -name=sqe_100write_4k -- 100%随机,70%读,30%写 4K fio -filename=/dev/emcpowerb -direct=1 -iodepth 1 -thread -rw=randrw -rwmixread=70 -ioengine=psync -bs=4k -size=1000G -numjobs=50 -runtime=180 -group_reporting -name=randrw_70read_4k |
测试场景
顺序读
顺序读注意,bs 单次io的块文件大小,我们建议可以设置为数据库的块或页大小,在真实的环境中或以调大size
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | # 顺序读注意,bs 单次io的块文件大小,我们建议可以设置为数据库的块或页大小,在真实的环境中或以调大size fio -filename=/dev/sda1 -direct=1 -iodepth= 1 -rw=read -ioengine=psync -bs=4k -size=1000G -numjobs=50 -runtime=180 -group_reporting -name=sqe_100read_4k [root@s2ahumysqlpg01 tmp]# fio -filename=/tmp/read.dat -direct=1 -iodepth 1 -rw=read -ioengine=psync -bs=4k -size=4G -numjobs=1 -runtime=180 -group_reporting -name=sqe_100read_4k sqe_100read_4k: (g=0): rw=read, bs=(R) 4096B-4096B, (W) 4096B-4096B, (T) 4096B-4096B, ioengine=psync, iodepth=1 fio-3.29 Starting 1 process sqe_100read_4k: Laying out IO file (1 file / 4096MiB) Jobs: 1 (f=1): [R(1)][100.0%][r=8372KiB/s][r=2093 IOPS][eta 00m:00s]ta 00m:56s] sqe_100read_4k: (groupid=0, jobs=1): err= 0: pid=5685: Fri Mar 4 17:42:10 2022 read: IOPS=3317, BW=13.0MiB/s (13.6MB/s)(2332MiB/180001msec) clat (usec): min=209, max=535634, avg=296.20, stdev=1443.62 lat (usec): min=210, max=535635, avg=297.13, stdev=1443.62 clat percentiles (usec): | 1.00th=[ 233], 5.00th=[ 241], 10.00th=[ 243], 20.00th=[ 247], | 30.00th=[ 251], 40.00th=[ 253], 50.00th=[ 258], 60.00th=[ 265], | 70.00th=[ 269], 80.00th=[ 281], 90.00th=[ 302], 95.00th=[ 330], | 99.00th=[ 627], 99.50th=[ 1074], 99.90th=[ 4817], 99.95th=[ 9896], | 99.99th=[34866] bw ( KiB/s): min= 32, max=15432, per=100.00%, avg=13284.66, stdev=2559.17, samples=359 iops : min= 8, max= 3858, avg=3321.16, stdev=639.79, samples=359 lat (usec) : 250=28.88%, 500=69.77%, 750=0.58%, 1000=0.21% lat (msec) : 2=0.36%, 4=0.08%, 10=0.06%, 20=0.03%, 50=0.02% lat (msec) : 100=0.01%, 250=0.01%, 500=0.01%, 750=0.01% cpu : usr=3.56%, sys=7.57%, ctx=597121, majf=0, minf=14 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 rwts: total=597112,0,0,0 short=0,0,0,0 dropped=0,0,0,0 latency : target=0, window=0, percentile=100.00%, depth=1 Run status group 0 (all jobs): READ: bw=13.0MiB/s (13.6MB/s), 13.0MiB/s-13.0MiB/s (13.6MB/s-13.6MB/s), io=2332MiB (2446MB), run=180001-180001msec Disk stats (read/write): sda: ios=599673/169, merge=2/7, ticks=185089/422, in_queue=184716, util=90.06% |
我们需要得点关注的是IOPS :3317 以及BW IO带宽是:13.0MiB/s
read: IOPS=3317, BW=13.0MiB/s (13.6MB/s)(2332MiB/180001msec)
随机写
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | #随机写 -rw=randwrite ,我们启用了50个进程模拟 [root@s2ahumysqlpg01 fio-3.29]# fio -filename=/tmp/write.dat -direct=1 -iodepth 1 -rw=randwrite -ioengine=psync -bs=4k -size=4G -numjobs=50 -runtime=180 -group_reporting -name=sqe_100write_4k sqe_100write_4k: (g=0): rw=randwrite, bs=(R) 4096B-4096B, (W) 4096B-4096B, (T) 4096B-4096B, ioengine=psync, iodepth=1 ... fio-3.29 Starting 50 processes sqe_100write_4k: Laying out IO file (1 file / 4096MiB) Jobs: 50 (f=50): [w(50)][100.0%][w=3692KiB/s][w=923 IOPS][eta 00m:00s] sqe_100write_4k: (groupid=0, jobs=50): err= 0: pid=7128: Fri Mar 4 17:54:18 2022 write: IOPS=1108, BW=4434KiB/s (4540kB/s)(781MiB/180331msec); 0 zone resets clat (usec): min=311, max=5969.7k, avg=45097.62, stdev=236640.38 lat (usec): min=313, max=5969.7k, avg=45098.90, stdev=236640.39 clat percentiles (usec): | 1.00th=[ 750], 5.00th=[ 1057], 10.00th=[ 1303], | 20.00th=[ 1647], 30.00th=[ 1844], 40.00th=[ 2343], | 50.00th=[ 3064], 60.00th=[ 3687], 70.00th=[ 4047], | 80.00th=[ 4948], 90.00th=[ 22938], 95.00th=[ 164627], | 99.00th=[1283458], 99.50th=[1753220], 99.90th=[2634023], | 99.95th=[3640656], 99.99th=[5939135] bw ( KiB/s): min= 350, max=103337, per=100.00%, avg=7568.53, stdev=265.17, samples=10555 iops : min= 50, max=25811, avg=1887.29, stdev=66.26, samples=10555 lat (usec) : 500=0.09%, 750=0.95%, 1000=3.17% lat (msec) : 2=29.75%, 4=34.89%, 10=18.41%, 20=2.36%, 50=2.42% lat (msec) : 100=1.74%, 250=2.29%, 500=1.44%, 750=0.83%, 1000=0.34% lat (msec) : 2000=1.02%, >=2000=0.30% cpu : usr=0.03%, sys=0.15%, ctx=220103, majf=0, minf=821 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 rwts: total=0,199884,0,0 short=0,0,0,0 dropped=0,0,0,0 latency : target=0, window=0, percentile=100.00%, depth=1 Run status group 0 (all jobs): WRITE: bw=4434KiB/s (4540kB/s), 4434KiB/s-4434KiB/s (4540kB/s-4540kB/s), io=781MiB (819MB), run=180331-180331msec Disk stats (read/write): sda: ios=0/218756, merge=0/1942, ticks=0/9721312, in_queue=9809977, util=100.00% |
我们可以看到IOPS是1108 ,BW带宽只有 4434KiB/s
write: IOPS=1108, BW=4434KiB/s (4540kB/s)(781MiB/180331msec); 0 zone resets
随机读写混合
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | #70%随机读-rwmixread=70 ,30%随机写 [root@s2ahumysqlpg01 fio-3.29]# fio -filename=/tmp/read_write.dat -direct=1 -iodepth=1 -rw=randrw -rwmixread=70 -ioengine=psync -bs=4k -size=4G -numjobs=50 -runtime=180 -group_reporting -name=randrw_70read_4k randrw_70read_4k: (g=0): rw=randrw, bs=(R) 4096B-4096B, (W) 4096B-4096B, (T) 4096B-4096B, ioengine=psync, iodepth=1 ... fio-3.29 Starting 50 processes randrw_70read_4k: Laying out IO file (1 file / 4096MiB) Jobs: 6 (f=6): [m(1),_(7),m(1),_(7),m(1),_(4),m(1),_(6),m(1),_(14),m(1),_(6)][2.2%][r=10.9MiB/s,w=4884KiB/s][r=2801,w=1221 IOPS][eta 02h:11m:59s] randrw_70read_4k: (groupid=0, jobs=50): err= 0: pid=8027: Fri Mar 4 18:01:37 2022 read: IOPS=1802, BW=7209KiB/s (7382kB/s)(1268MiB/180113msec) clat (usec): min=225, max=3503.6k, avg=18238.79, stdev=55447.72 lat (usec): min=226, max=3503.6k, avg=18239.86, stdev=55447.72 clat percentiles (usec): | 1.00th=[ 330], 5.00th=[ 553], 10.00th=[ 635], | 20.00th=[ 799], 30.00th=[ 1074], 40.00th=[ 1631], | 50.00th=[ 3326], 60.00th=[ 8717], 70.00th=[ 17433], | 80.00th=[ 28967], 90.00th=[ 47973], 95.00th=[ 69731], | 99.00th=[ 147850], 99.50th=[ 196084], 99.90th=[ 429917], | 99.95th=[ 859833], 99.99th=[2936013] bw ( KiB/s): min= 350, max=25119, per=100.00%, avg=8438.00, stdev=106.40, samples=15326 iops : min= 50, max= 6272, avg=2094.52, stdev=26.64, samples=15326 write: IOPS=774, BW=3096KiB/s (3171kB/s)(545MiB/180113msec); 0 zone resets clat (usec): min=251, max=3576.5k, avg=22074.38, stdev=134044.57 lat (usec): min=252, max=3576.5k, avg=22075.53, stdev=134044.60 clat percentiles (usec): | 1.00th=[ 347], 5.00th=[ 537], 10.00th=[ 603], | 20.00th=[ 709], 30.00th=[ 816], 40.00th=[ 955], | 50.00th=[ 1188], 60.00th=[ 1565], 70.00th=[ 2311], | 80.00th=[ 4080], 90.00th=[ 9634], 95.00th=[ 35390], | 99.00th=[ 583009], 99.50th=[1082131], 99.90th=[1501561], | 99.95th=[1837106], 99.99th=[3472884] bw ( KiB/s): min= 350, max=13399, per=100.00%, avg=3753.05, stdev=51.84, samples=14762 iops : min= 50, max= 3343, avg=923.38, stdev=13.00, samples=14762 lat (usec) : 250=0.06%, 500=2.99%, 750=16.22%, 1000=12.87% lat (msec) : 2=18.13%, 4=10.02%, 10=10.01%, 20=8.68%, 50=13.12% lat (msec) : 100=5.06%, 250=1.98%, 500=0.44%, 750=0.11%, 1000=0.09% lat (msec) : 2000=0.18%, >=2000=0.02% cpu : usr=0.06%, sys=0.14%, ctx=488255, majf=0, minf=1027 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 rwts: total=324593,139424,0,0 short=0,0,0,0 dropped=0,0,0,0 latency : target=0, window=0, percentile=100.00%, depth=1 Run status group 0 (all jobs): READ: bw=7209KiB/s (7382kB/s), 7209KiB/s-7209KiB/s (7382kB/s-7382kB/s), io=1268MiB (1330MB), run=180113-180113msec WRITE: bw=3096KiB/s (3171kB/s), 3096KiB/s-3096KiB/s (3171kB/s-3171kB/s), io=545MiB (571MB), run=180113-180113msec Disk stats (read/write): sda: ios=324721/139458, merge=0/2, ticks=5905787/3076202, in_queue=8984158, util=100.00% |
从结果中我们可以看到70%随机读的IOPS 是1802 ,30%随机写是774 ,而带宽分别是7209KiB/s,3096KiB/s。
read: IOPS=1802, BW=7209KiB/s (7382kB/s)(1268MiB/180113msec)
write: IOPS=774, BW=3096KiB/s (3171kB/s)(545MiB/180113msec); 0 zone resets
压测结果解读
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 | [root@dbm-01 data]# fio fio.cfg 4k-write: (g=0): rw=write, bs=(R) 4096B-4096B, (W) 4096B-4096B, (T) 4096B-4096B, ioengine=libaio, iodepth=1 ... 4k-randwrite: (g=1): rw=randwrite, bs=(R) 4096B-4096B, (W) 4096B-4096B, (T) 4096B-4096B, ioengine=libaio, iodepth=1 ... fio-3.7 Starting 60 threads Jobs: 30 (f=30): [_(30),w(30)][11.9%][r=0KiB/s,w=192MiB/s][r=0,w=49.3k IOPS][eta 24m:37s] 4k-write: (groupid=0, jobs=30): err= 0: pid=14529: Tue Nov 23 20:12:08 2021 write: IOPS=106k, BW=415MiB/s (435MB/s)(40.5GiB/100002msec) slat (usec): min=3, max=14296, avg=23.86, stdev=34.22 clat (nsec): min=993, max=20735k, avg=257999.15, stdev=63006.92 lat (usec): min=30, max=20773, avg=281.97, stdev=70.00 clat percentiles (usec): | 1.00th=[ 227], 5.00th=[ 237], 10.00th=[ 239], 20.00th=[ 243], | 30.00th=[ 247], 40.00th=[ 251], 50.00th=[ 255], 60.00th=[ 260], | 70.00th=[ 265], 80.00th=[ 269], 90.00th=[ 273], 95.00th=[ 277], | 99.00th=[ 293], 99.50th=[ 363], 99.90th=[ 1270], 99.95th=[ 1467], | 99.99th=[ 1762] bw ( KiB/s): min= 9835, max=13978, per=2.62%, avg=11137.60, stdev=415.24, samples=5970 iops : min= 2458, max= 3494, avg=2784.02, stdev=103.82, samples=5970 lat (nsec) : 1000=0.01% lat (usec) : 2=0.01%, 4=0.01%, 10=0.01%, 20=0.01%, 50=0.03% lat (usec) : 100=0.17%, 250=36.97%, 500=62.44%, 750=0.20%, 1000=0.03% lat (msec) : 2=0.15%, 4=0.01%, 10=0.01%, 20=0.01%, 50=0.01% cpu : usr=0.93%, sys=11.32%, ctx=10740093, majf=0, minf=2817 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 rwts: total=0,10614582,0,0 short=0,0,0,0 dropped=0,0,0,0 latency : target=0, window=0, percentile=100.00%, depth=1 4k-randwrite: (groupid=1, jobs=30): err= 0: pid=17275: Tue Nov 23 20:12:08 2021 write: IOPS=50.2k, BW=196MiB/s (205MB/s)(19.1GiB/100002msec) slat (usec): min=3, max=10742, avg=23.21, stdev=21.85 clat (nsec): min=825, max=21466k, avg=573943.92, stdev=468815.81 lat (usec): min=50, max=22154, avg=597.26, stdev=469.11 clat percentiles (usec): | 1.00th=[ 289], 5.00th=[ 302], 10.00th=[ 306], 20.00th=[ 318], | 30.00th=[ 322], 40.00th=[ 334], 50.00th=[ 347], 60.00th=[ 553], | 70.00th=[ 603], 80.00th=[ 627], 90.00th=[ 693], 95.00th=[ 1926], | 99.00th=[ 2073], 99.50th=[ 2114], 99.90th=[ 2180], 99.95th=[ 2245], | 99.99th=[ 3228] bw ( KiB/s): min= 5408, max=10163, per=3.33%, avg=6685.70, stdev=288.97, samples=5977 iops : min= 1352, max= 2540, avg=1671.39, stdev=72.24, samples=5977 lat (nsec) : 1000=0.01% lat (usec) : 2=0.01%, 4=0.01%, 10=0.01%, 20=0.01%, 50=0.01% lat (usec) : 100=0.03%, 250=0.18%, 500=57.83%, 750=32.05%, 1000=0.23% lat (msec) : 2=6.91%, 4=2.76%, 10=0.01%, 20=0.01%, 50=0.01% cpu : usr=0.46%, sys=4.98%, ctx=5064328, majf=0, minf=55804 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 rwts: total=0,5015251,0,0 short=0,0,0,0 dropped=0,0,0,0 latency : target=0, window=0, percentile=100.00%, depth=1 Run status group 0 (all jobs): WRITE: bw=415MiB/s (435MB/s), 415MiB/s-415MiB/s (435MB/s-435MB/s), io=40.5GiB (43.5GB), run=100002-100002msec Run status group 1 (all jobs): WRITE: bw=196MiB/s (205MB/s), 196MiB/s-196MiB/s (205MB/s-205MB/s), io=19.1GiB (20.5GB), run=100002-100002msec Disk stats (read/write): sdb: ios=66/15648881, merge=0/23534, ticks=17/5617878, in_queue=5613375, util=99.94% |
报告参数解释 ,通常我们关注 io,iops,clat
bw 表示测试中达到的平均带宽
clat 表示完成延迟(completion latency) - 完成延迟是提交请求和请求完成之间的时间。统计值分别是最小、最大、平均和标准方差。
CPU 行数据显示IO负载对CPU的影响
IO depths 段落对于测试多请求的IO负载非常有意义 - 由于上述测试所有测试是单IO请求,所以IO depths始终100%是1
三行 lat 显示了每个IO请求完成的概况,例如,上述延迟在2ms的占68.84%,1ms(1000us)占21.36%
READ 行显示了读取速率
详细的解释如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | io=执行了多少M的IO bw=平均IO带宽 iops=IOPS runt=线程运行时间 slat=提交延迟 clat=完成延迟 lat=响应时间 bw=带宽 cpu=利用率 IO depths=io队列 IO submit=单个IO提交要提交的IO数 IO complete=Like the above submit number, but for completions instead. IO issued=The number of read/write requests issued, and how many of them were short. IO latencies=IO完延迟的分布 io=总共执行了多少size的IO aggrb=group总带宽 minb=最小.平均带宽. maxb=最大平均带宽. mint=group中线程的最短运行时间. maxt=group中线程的最长运行时间. ios=所有group总共执行的IO数. merge=总共发生的IO合并数. ticks=Number of ticks we kept the disk busy. io_queue=花费在队列上的总共时间. util=磁盘利用率 |
关于gcc 版本过低问题
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | [root@s2ahumysqlpg01 fio-3.29]# ./configure Operating system Linux CPU x86_64 Big endian no Compiler gcc Cross compile no Static build no Your compiler doesn't support C11 atomics. gcc 4.9/clang 3.6 are the minimum versions with it - perhaps your compiler is too old? C11 atomics support not found Configure failed, check config.log and/or the above output |
解决:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | # 升级gcc 版本到 5.2 ## 1.安装centos-release-scl 工具 wget http://mirror.centos.org/centos/7/extras/x86_64/Packages/centos-release-scl-2-3.el7.centos.noarch.rpm wget http://mirror.centos.org/centos/7/extras/x86_64/Packages/centos-release-scl-rh-2-3.el7.centos.noarch.rpm [root@s2ahumysqlpg01 yum.repos.d]# rpm -ivh *.rpm warning: centos-release-scl-2-3.el7.centos.noarch.rpm: Header V3 RSA/SHA256 Signature, key ID f4a80eb5: NOKEY Preparing... ################################# [100%] Updating / installing... 1:centos-release-scl-rh-2-3.el7.cen################################# [ 50%] 2:centos-release-scl-2-3.el7.centos################################# [100%] #2.安装devtoolset,注意,如果想安装7.*版本的,就改成devtoolset-7-gcc*,以此类推 yum install centos-release-scl #3. 激活对应的devtoolset,所以你可以一次安装多个版本的devtoolset,需要的时候用下面这条命令切换到对应的版本 enable devtoolset-8 bash #4.查看一下gcc版本 gcc -v #5. 这条激活命令只对本次会话有效,重启会话后还是会变回原来的4.8.5版本,如下操作可以直接替换旧的gcc 旧的gcc是运行的 /usr/bin/gcc,所以将该目录下的gcc/g++替换为刚安装的新版本gcc软连接,免得每次enable , 一般个人不建议直接替换 mv /usr/bin/gcc /usr/bin/gcc-4.8.5 ln -s /opt/rh/devtoolset-8/root/bin/gcc /usr/bin/gcc mv /usr/bin/g++ /usr/bin/g++-4.8.5 ln -s /opt/rh/devtoolset-8/root/bin/g++ /usr/bin/g++ gcc --version g++ --version |
图形界面gfio
fio是个非常强大的IO性能测试工具,可以毫不夸张的说,如果你把所有的fio参数都搞明白了,基本上就把IO协议栈的问题搞的差不多明白了,原因在于作者Jens Axboe是linux内核IO部分的maintainer. 但是这个工具有个很大的缺点就是没有图形界面,单靠输出的数字很难看出来IO的趋势变化,所以急需一个图形前端.
幸运的是Jens也认识到这个问题,2012年2月15号在google plus上说:
Once complete, this will be a great addition to fio. It can be quite tricky to get a good overview of all the various job controlling options that fio has, presenting them graphically has some advantages over a basic 80-line text cli.
可是Jens是写linux内核代码的,对于图形终端的编程不是很熟悉。 大牛毕竟是大牛,发扬革命不怕苦精神,自己学图形编程,于是在最近的2.1版本给我们带来了这个图形终端。有了这个东西使用起来就方便许多。
我给大家演示下如何编译,运行这个gfio. 在这之前需要给大家说下fio的server/client模式。 fio一旦进入server模式就会在8765 tcp端口上监听,等待客户端来连接。 一旦客户端连接上来,会发上来比如运行job等任务,服务端把运行结果推送到客户端。所以这个图形前端实际上是fio的一个client, 名字叫gfio. 具体参见 README里面的描述。
新版本的支持gfio的fio可以在这里下载 git clone git://git.kernel.dk/fio.git,编译gfio源码的时候, 由于它依赖于gtk库,需要先安装libgtk2.0开发包,演示开始:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | $ uname -a Linux yufeng-Latitude-E6400 3.0.0-30-generic #47-Ubuntu SMP Wed Jan 2 23:16:29 UTC 2013 x86_64 x86_64 x86_64 GNU/Linux $ sudo apt-get -y install libgtk2.0-dev $ git clone git://git.kernel.dk/fio.git $ cd fio $ ./configure --enable-gfio ... gtk 2.18 or higher yes ... $ make fio $ make gfio $ ./fio -S fio: server listening on 0.0.0.0,8765 |
这样fio就编译好了,同时进入server模式。 在另外一个终端运行 gfio 就可以看到图形界面,打开examples/aio-read.fio 这个脚本把玩下(注意这个脚本里面文件的路径是/data1, 最好改成/tmp之类的),如下图:
fio数据生成曲线图工具之fio2gnuplot
1、背景
我们常常在测试fio的时候,一般只会看到最终测试结果。如下所示
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | [root@localhost zhangyi]# fio --filename=test_file --direct=1 --rw=randwrite --numjobs=1 --iodepth=16 --ioengine=libaio --bs=4k --group_reporting --name=zhangyi --log_avg_msec=500 --write_bw_log=test-fio --size=1G zhangyi: (g=0): rw=randwrite, bs=4K-4K/4K-4K/4K-4K, ioengine=libaio, iodepth=16 fio-2.2.8 Starting 1 process zhangyi: Laying out IO file(s) (1 file(s) / 1024MB) Jobs: 1 (f=1): [w(1)] [100.0% done] [0KB/49649KB/0KB /s] [0/12.5K/0 iops] [eta 00m:00s] zhangyi: (groupid=0, jobs=1): err= 0: pid=3143: Wed Aug 30 15:37:18 2017 write: io=1024.0MB, bw=48438KB/s, iops=12109, runt= 21648msec slat (usec): min=2, max=8200, avg=59.44, stdev=75.52 clat (usec): min=42, max=17377, avg=1259.63, stdev=847.23 lat (usec): min=122, max=17383, avg=1319.47, stdev=862.50 clat percentiles (usec): | 1.00th=[ 580], 5.00th=[ 652], 10.00th=[ 692], 20.00th=[ 780], | 30.00th=[ 860], 40.00th=[ 948], 50.00th=[ 1048], 60.00th=[ 1160], | 70.00th=[ 1256], 80.00th=[ 1368], 90.00th=[ 2224], 95.00th=[ 2864], | 99.00th=[ 3824], 99.50th=[ 4384], 99.90th=[10688], 99.95th=[13376], | 99.99th=[16064] bw (KB /s): min=43072, max=52968, per=99.85%, avg=48362.74, stdev=2721.66 lat (usec) : 50=0.01%, 250=0.02%, 500=0.25%, 750=16.72%, 1000=29.09% lat (msec) : 2=41.80%, 4=11.37%, 10=0.60%, 20=0.14% cpu : usr=1.19%, sys=71.85%, ctx=80337, majf=0, minf=31 IO depths : 1=0.1%, 2=0.1%, 4=0.1%, 8=0.1%, 16=100.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.1%, 32=0.0%, 64=0.0%, >=64=0.0% issued : total=r=0/w=262144/d=0, short=r=0/w=0/d=0, drop=r=0/w=0/d=0 latency : target=0, window=0, percentile=100.00%, depth=16 Run status group 0 (all jobs): WRITE: io=1024.0MB, aggrb=48437KB/s, minb=48437KB/s, maxb=48437KB/s, mint=21648msec, maxt=21648msec Disk stats (read/write): dm-0: ios=2/263339, merge=0/0, ticks=130/102093, in_queue=102223, util=93.14%, aggrios=2/270086, aggrmerge=0/18, aggrticks=130/100523, aggrin_queue=100545, aggrutil=92.82% 123456789101112131415161718192021222324252627282930 |
这样只能看到一个结果,而中间过程的IO情况则看不到。所以这里介绍一个方法,可以将fio中间过程的数据抓出来绘制成图的方法。
2、安装gnuplot
1 2 | sudo yum install gnuplot 1 |
最终回安装两个包:
1 2 3 4 | [root@localhost zhangyi]# rpm -qa |grep gnuplot gnuplot-common-4.6.2-3.el7.x86_64 gnuplot-4.6.2-3.el7.x86_64 123 |
3、对一个文件执行fio操作
1 2 3 4 5 | fio --filename=test_file --direct=1 --rw=randwrite -- numjobs=1 --iodepth=16 --ioengine=libaio --bs=4k --group_reporting --name=zhangyi --log_avg_msec=500 --write_bw_log=test-fio --size=1G 1234 |
这里需要说明下的就是write_bw_log这个参数需要指定,意思就是将fio的输出带宽信息就到文件test-fio中。这里可以指定带宽,IOPS和延时
1 2 3 | write_bw_log=fio-test write_iops_log=fio-test write_lat_log=fio-test |
运行完成后可以生成如下文件:
1 | -rw-r--r--. 1 root root 797 Aug 30 15:37 test-fio_bw.1.log |
这个文件就记录了fio运行期间的带宽数据。
1 2 3 4 5 6 7 8 | [root@localhost zhangyi]# cat test-fio_bw.1.log 500, 50648, 1, 0 1000, 49328, 1, 0 1500, 49096, 1, 0 2000, 49824, 1, 0 2500, 51120, 1, 0 3000, 47472, 1, 0 3500, 49976, 1, 0 |
这里表示每log_avg_msec=500ms记录一次。这个参数也可以调整。
绘图
将这个test-fio_bw.1.log修改成test-fio_bw.log,因为fio2gnuplot会默认在当前目录下寻找*_bw.log文件。
1 2 3 4 5 | [root@localhost zhangyi]# fio2gnuplot -b -g 1 files Selected with pattern '*_bw.log' |-> test-fio_bw.log Running gnuplot Rendering Rendering traces are available in the current directory |
这里b的意思就是绘制带宽的图,-i则表示绘制iops的图,但是貌似现在gnuplot不支持iops和latency的绘制。不要在乎这些细节。执行完成后会生成如下几个文件:
1 2 3 4 | -rw-r--r--. 1 root root 13K Aug 30 15:51 test-fio_bw-2Draw.png -rw-r--r--. 1 root root 12K Aug 30 15:51 test-fio_bw-2Dsmooth.png -rw-r--r--. 1 root root 10K Aug 30 15:51 test-fio_bw-2Dtrend.png 123 |
打开文件
fio数据生成曲线图工具之fio_generate_plots bw
也可以用fio_generate_plots bw的方式来生成图像
fio安装完后自带有一个高级脚本fio_generate_plots能够根据fio输出的数据进行画图。操作流程如下:
1.1设置fio输出详细日志
fio的输出日志主要包含三种:bw,lat和iops,设置这三种的参数如下:
1 2 3 | write_bw_log=rw write_lat_log=rw write_iops_log=rw |
这里需要强调的一点是,后面接的参数rw,是输出日志文件名的prefix,如最终会生成的日志文件如下:
1 2 3 4 5 | rw_iops.log rw_clat.log rw_slat.log rw_lat.log rw_bw.log |
这个参数在后面画图的时候也要用到。
1 | for i in clat lat slat bw iops;do mv rbd_$i.1.log rbd_$i.log;done |
画图
前提是还需要安装好gnuplot,然后使用下面的命令即可自动画图:
1 | root@ubuntu:/tmp> fio_generate_plots bw |
发现没有,fio_generate_plots接受的唯一参数就是这个日志文件名的prefix。
本例中生成的图片文件有:
bw-bw.svg
bw-clat.svg
bw-iops.svg
bw-lat.svg
bw-slat.svg
总结
1 2 3 4 5 6 7 8 9 | fio -filename=/tmp/read_write.dat -direct=1 -iodepth=1 -rw=randrw -rwmixread=70 \ -ioengine=psync -bs=32k -size=6G -numjobs=12 -runtime=180 -group_reporting -name=randrw_70read_32k iostat -dxk 5 sar -d -p 2 iotop -b -o -d 2 -t -qqq -n 5 iotop -o -d 2 iotop -botq -p PID pidstat -r -p PID 2 |
参考
https://www.cnblogs.com/raykuan/p/6914748.html
https://huataihuang.gitbooks.io/cloud-atlas/content/performance/utilities/fio.html
https://blog.51cto.com/u_12993908/5275922
http://blog.yufeng.info/archives/2721
https://blog.csdn.net/weixin_37871174/article/details/77717633