安装工具
安装fio工具的方法有源码编译,rpm包,yum安装,推荐安装方式是源码编译和rpm来安装。
- 源码编译
https://github.com/axboe/fio/archive/refs/tags/fio-3.33.tar.gz
在fio官网下载fio-3.33.tar.gz文件,解压后./configure、make&&make install之后就可以使用fio了。 - rpm包安装
https://pkgs.org/download/fio
选择合适系统的rpm包就行安装即可。 - yum安装
yum install -y fio
fio参数解析
使用fio -help查看每个参数,具体的参数可以在官网查看,如下为几个常见的参数描述
filename=/dev/emcpowerb 支持文件系统或者裸设备,-filename=/dev/sda2或-filename=/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=5g 本次的测试文件大小为5g,以每次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 每个进程生成文件的数量
ioengine参数,这个就是告诉 fio 使用什么样的方式去测试 I/O,我们需要根据业务的实际情况选择不同的类型,主要几个:
- libaio - Linux 原生的异步 I/O,这也是通常我们这边用的最多的测试盘吞吐和延迟的方法
- sync - 也就是最通常的 read / write 操作
- vsync - 使用 readv / writev,主要是会将相邻的 I/O 进行合并
- psync - 对应的 pread / pwrite,增量同步,一般sync是全量的
- pvsync / pvsync2 - 对应的 preadv / pwritev,以及 preadv2 / pwritev2
测试实践
MogDB数据库是以8kb为单位写入文件系统,所以测试本地盘,sata盘,ssd盘的顺序写 8kb的块 的能力分别是怎样的
-- 顺序写 单并发 8K 10G gaussdata盘为例
[root@test 8kseq]# more 8kseq.fio
[global]
bs=8k
ioengine=libaio
iodepth=4
size=10G
direct=1
runtime=60
directory=/gaussdata
filename=8kseq
[seq-write]
rw=write
stonewall
-- 顺序写 8K 10并发 每并发写1G gaussdata盘为例
[root@test 8kseq]# more 8kseq.fio.10
[global]
bs=8k
ioengine=libaio
iodepth=4
direct=1
runtime=100
directory=/gaussdata
nrfiles=1
filesize=1G
numjobs=10
[seq-write]
rw=write
stonewall
-- 顺序写 8K 50并发 每并发写1G gaussdata盘为例
[root@test 8kseq]# more 8kseq.fio.50
[global]
bs=8k
ioengine=libaio
iodepth=4
direct=1
runtime=100
directory=/gaussdata
nrfiles=1
filesize=1G
numjobs=50
[seq-write]
rw=write
stonewall
测试结果
本地盘

sata盘

ssd盘

以下列返回结果为实例分析
rand-write: (g=0): rw=write, bs=(R) 64.0KiB-64.0KiB, (W) 64.0KiB-64.0KiB, (T) 64.0KiB-64.0KiB, ioengine=sync, iodepth=4
fio-3.33
Starting 1 process
rand-write: Laying out IO file (1 file / 10240MiB)
note: both iodepth >= 1 and synchronous I/O engine are selected, queue depth will be capped at 1
Jobs: 1 (f=1): [W(1)][100.0%][w=51.9MiB/s][w=830 IOPS][eta 00m:00s]
rand-write: (groupid=0, jobs=1): err= 0: pid=58951: Wed Nov 9 15:06:02 2022
write: IOPS=885, BW=55.3MiB/s (58.0MB/s)(5534MiB/100001msec); 0 zone resets
clat (usec): min=872, max=43635, avg=1128.27, stdev=750.92
lat (usec): min=873, max=43635, avg=1128.71, stdev=750.92
clat percentiles (usec):
| 1.00th=[ 947], 5.00th=[ 988], 10.00th=[ 1012], 20.00th=[ 1037],
| 30.00th=[ 1057], 40.00th=[ 1074], 50.00th=[ 1106], 60.00th=[ 1123],
| 70.00th=[ 1139], 80.00th=[ 1172], 90.00th=[ 1221], 95.00th=[ 1287],
| 99.00th=[ 1467], 99.50th=[ 1614], 99.90th=[ 2704], 99.95th=[ 5342],
| 99.99th=[40109]
bw ( KiB/s): min=46080, max=60160, per=100.00%, avg=56741.95, stdev=2691.56, samples=199
iops : min= 720, max= 940, avg=886.59, stdev=42.06, samples=199
lat (usec) : 1000=7.86%
lat (msec) : 2=91.92%, 4=0.16%, 10=0.02%, 50=0.04%
cpu : usr=0.08%, sys=1.03%, ctx=88572, majf=0, minf=7
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,88547,0,0 short=0,0,0,0 dropped=0,0,0,0
latency : target=0, window=0, percentile=100.00%, depth=4
Run status group 0 (all jobs):
WRITE: bw=55.3MiB/s (58.0MB/s), 55.3MiB/s-55.3MiB/s (58.0MB/s-58.0MB/s), io=5534MiB (5803MB), run=100001-100001msec
Disk stats (read/write):
dm-14: ios=0/89284, merge=0/0, ticks=0/98850, in_queue=98850, util=98.86%, aggrios=0/88735, aggrmerge=0/683, aggrticks=0/99534, aggrin_queue=1140, aggrutil=99.09%
dm-13: ios=0/88735, merge=0/683, ticks=0/99534, in_queue=1140, util=99.09%, aggrios=0/29578, aggrmerge=0/0, aggrticks=0/33014, aggrin_queue=380, aggrutil=34.27%
sdm: ios=0/29575, merge=0/0, ticks=0/33411, in_queue=540, util=33.42%
sdn: ios=0/29585, merge=0/0, ticks=0/33342, in_queue=540, util=34.27%
sdl: ios=0/29575, merge=0/0, ticks=0/32289, in_queue=60, util=30.98%
运行时,fio将显示已创建作业的状态。示例中为:
Jobs: 1 (f=1): [W(1)][100.0%][w=51.9MiB/s][w=830 IOPS][eta 00m:00s]
当前运行和执行I/O的线程数为1,当前打开的文件数(f=)为1。
第一组括号中的字符表示每个线程的当前状态,示例中为W,表示顺序写。当为R时,表示顺序读;r表示随机读;w表示随机写;M表示混合顺序读/写;m表示混合随机读/写。
第二组括号显示当前估计完成百分比,因为已经命令已经执行完,所以是100%。第三组括号分别显示读取和写入I/O速率。第四组括号以带宽和IOPS表示第三组括号的内容,最后,将显示预估的作业剩余运行时间。
当fio完成时(或被Ctrl-C中断),它将按顺序显示每个线程、每组线程和每个磁盘的数据。
write: IOPS=885, BW=55.3MiB/s (58.0MB/s)(5534MiB/100001msec); 0 zone resets
IOPS是每秒执行的平均I/O。BW是平均带宽速率也叫吞吐量,示例中 55.3MiB/s = 58.0MB/s。最后两个值为:(执行的总I/O / 线程运行时间)。
clat (usec): min=872, max=43635, avg=1128.27, stdev=750.92
lat (usec): min=873, max=43635, avg=1128.71, stdev=750.92
有的上面还有slat,slat是提交I/O所用的时间,即提交延迟(最小值,最大值,平均值,标准偏差)。在上面的示例中,单位是纳秒。
clat与slat的名称类似,表示从提交到完成I/O的时间。
lat表示总延迟。与slat和clat的名称类似,表示从fio创建I/O单元到完成I/O操作的时间,得到的就是响应时间。
bw ( KiB/s): min=46080, max=60160, per=100.00%, avg=56741.95, stdev=2691.56, samples=199
bw表示基于sample的带宽统计。包括采样数(samples)和该线程占用总聚合带宽的近似百分比(per)。
iops : min= 720, max= 940, avg=886.59, stdev=42.06, samples=199
基于sample的IOPS统计信息。与bw同名。
lat (usec) : 1000=7.86%
lat (msec) : 2=91.92%, 4=0.16%, 10=0.02%, 50=0.04%
I/O完成延迟的分布。这是从I/O离开fio到完成的时间。本例中,1000=7.86%表示 7.86% 的I/O在1000us以下完成。
cpu : usr=0.08%, sys=1.03%, ctx=88572, majf=0, minf=7
CPU使用率。用户和系统时间使用率,以及这个线程经历的上下文切换的数量(ctx),最后是主要(majf)和次要(minf)页面错误的数量。
IO depths : 1=100.0%, 2=0.0%, 4=0.0%, 8=0.0%, 16=0.0%, 32=0.0%, >=64=0.0%
在作业生命周期内I/O深度的分布。数字被划分为2的幂,每个条目覆盖从该值到低于下一个条目的深度,例如,1=覆盖从1到2的深度。
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在一次提交调用中提交了多少个I/O。每个条目都表示该数值及其以下,直到上一个条目——例如,4=100%表示我们在每次提交调用中提交了1到4个I/O。
complete与上述submit编号相同,但用于完成。
issued rwts: total=0,88547,0,0 short=0,0,0,0 dropped=0,0,0,0
发出的读/写/修剪请求的数量,以及其中有多少是短请求或丢弃的。
列出每个client后,将打印组统计信息。看起来像这样:
Run status group 0 (all jobs):
WRITE: bw=55.3MiB/s (58.0MB/s), 55.3MiB/s-55.3MiB/s (58.0MB/s-58.0MB/s), io=5534MiB (5803MB), run=100001-100001msec
bw表示此组中线程的聚合带宽,然后是此组中所有线程的最小和最大带宽。
io表示该组中所有线程执行的I/O,格式与bw相同。
run表示此组中线程的最短和最长运行时间。
最后,打印磁盘统计信息。这是Linux特有的,看起来像这样:
Disk stats (read/write):
dm-14: ios=0/89284, merge=0/0, ticks=0/98850, in_queue=98850, util=98.86%, aggrios=0/88735, aggrmerge=0/683, aggrticks=0/99534, aggrin_queue=1140, aggrutil=99.09%
dm-13: ios=0/88735, merge=0/683, ticks=0/99534, in_queue=1140, util=99.09%, aggrios=0/29578, aggrmerge=0/0, aggrticks=0/33014, aggrin_queue=380, aggrutil=34.27%
sdm: ios=0/29575, merge=0/0, ticks=0/33411, in_queue=540, util=33.42%
sdn: ios=0/29585, merge=0/0, ticks=0/33342, in_queue=540, util=34.27%
sdl: ios=0/29575, merge=0/0, ticks=0/32289, in_queue=60, util=30.98%
每个值都会输出读和写的值,读的值在前。
ios表示所有组执行的I/O数。
merge表示I/O计划程序执行的合并数。
ticks表示磁盘忙的滴答数。
in_queue表示在磁盘队列中花费的总时间。
util表示磁盘利用率。值为100%意味着磁盘一直处于繁忙状态,50%意味着磁盘有一半时间处于空闲状态。
参考文档
https://blog.csdn.net/zsx0728/article/details/122596125
https://www.bilibili.com/read/cv15021687
https://github.com/axboe/fio
https://fio.readthedocs.io/en/latest/fio_doc.html




