暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

fio工具测试

原创 何放 2023-08-05
1793

安装工具

安装fio工具的方法有源码编译,rpm包,yum安装,推荐安装方式是源码编译和rpm来安装。

  1. 源码编译
    https://github.com/axboe/fio/archive/refs/tags/fio-3.33.tar.gz
    在fio官网下载fio-3.33.tar.gz文件,解压后./configure、make&&make install之后就可以使用fio了。
  2. rpm包安装
    https://pkgs.org/download/fio
    选择合适系统的rpm包就行安装即可。
  3. 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

测试结果

本地盘
image.png
sata盘
image.png
ssd盘
image.png
以下列返回结果为实例分析

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

最后修改时间:2023-08-05 15:29:34
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论