fio 一个 Linux 磁盘压测工具


官方文档:fio_doc

  • 别真的以为人家只支持 Linux,其实官方还有 windows 的安装方法的

安装 fio

安装方法有很多,具体可以参考官方文档,从二进制文件到编译都有,我这边是 rocky linux,可以直接 yum 安装,debian 系列的,可以 apt 安装

yum install -y fio
# 当然,你要用 dnf 也没问题

Job file 的方式

  • Job file 格式是经典的 ini 文件,其中 [] 括号中的名称定义 job 名称。
  • 您可以随意使用任何您想要的 ASCII 名称,但具有特殊含义的 global 除外。
  • job 名称后面是零个或多个参数的序列,每行一个参数,用于定义 job 的行为。
  • 如果一行中的第一个字符是 ;#,则整行将作为注释丢弃。

创建一个 Job file ,内容类似下面这样,这是同时开启随机读写的两个任务

[global]
# 使用异步 I/O 引擎
ioengine=libaio
# 启动 4 个并发工作线程
numjobs=4
# 随机读写
rw=randrw
# 块大小
bs=4k
# 每个线程测试文件的大小
size=1G
# 运行时间,不写单位表示秒
runtime=60
# 基于时间的测试
time_based
# 汇总报告
group_reporting

[randrw_test]
# 测试文件路径
filename=/tmp/randrw_testfile
  • ioengine

    • ioengine:linux 下的异步引擎,其他的,详见官方文档
  • readwrite=str, rw=str

    • read:顺序读取
    • write:顺序写入
    • trim:顺序修剪(仅限 Linux 块设备和 SCSI 字符设备)
    • randread:随机读取
    • randwrite:随机写入
    • randtrim:随机修剪(仅限 Linux 块设备和 SCSI 字符设备)
    • rw,readwrite:顺序混合读取和写入
    • randrw:随机混合读取和写入
    • trimwrite:顺序 trim+write 序列。
      • 首先修剪块,然后写入相同的块。因此,如果指定了io_size=64K,则 Fio 将修剪总共 64K 字节,并在相同的修剪块上写入 64K 字节。此行为将与 number_ios 或其他限制总字节数或 I/O 数量的 Fio 选项一致。
    • randtrimwrite:与 trimwrite 类似,但使用随机偏移量而不是顺序写入
  • blocksize=int[,int][,int], bs=int[,int][,int]

    • block 块的大小,默认是 4096
    • bs=256k:表示 256k 用于读取、写入和修剪
    • bs=8k,32k:表示 8k 用于读取,32k 用于写入和 trim
    • bs=8k,32k,:表示 8k 用于读取,32k 用于写入,默认用于修剪
    • bs=,8k:表示 default 表示读取,8k 表示写入和 trim
    • bs=,8k,:表示 default 表示读取,8k 表示写入,default 表示 trims
  • 时间相关参数

    • runtime:指定 fio 运行多长时间后停止
    • time_based:fio 基于时间测试,即使文件达到 size 的大小,也不会听,直到 runtime 到了
    • 还有更多其他的,可以继续看官方文档

运行 fio

fio disk-test.fio

输出的结果

randrw_test: Laying out IO file (1 file / 1024MiB)
Jobs: 4 (f=4): [m(4)][100.0%][r=22.4MiB/s,w=23.0MiB/s][r=5745,w=5889 IOPS][eta 00m:00s]
randrw_test: (groupid=0, jobs=4): err= 0: pid=23995: Mon Oct 28 15:54:54 2024
  read: IOPS=10.0k, BW=39.2MiB/s (41.1MB/s)(2352MiB/60002msec)
    slat (nsec): min=1614, max=1209.4M, avg=198081.45, stdev=2970772.65
    clat (nsec): min=615, max=107632, avg=1949.24, stdev=1541.66
     lat (usec): min=2, max=1209.4k, avg=200.56, stdev=2970.90
    clat percentiles (nsec):
     |  1.00th=[  748],  5.00th=[  788], 10.00th=[  924], 20.00th=[  956],
     | 30.00th=[  996], 40.00th=[ 1704], 50.00th=[ 1912], 60.00th=[ 2096],
     | 70.00th=[ 2224], 80.00th=[ 2384], 90.00th=[ 2768], 95.00th=[ 3504],
     | 99.00th=[ 6240], 99.50th=[12352], 99.90th=[18304], 99.95th=[23424],
     | 99.99th=[33536]
   bw (  KiB/s): min= 2211, max=85120, per=100.00%, avg=40941.17, stdev=3783.36, samples=468
   iops        : min=  551, max=21280, avg=10235.14, stdev=945.87, samples=468
  write: IOPS=10.1k, BW=39.3MiB/s (41.2MB/s)(2356MiB/60002msec); 0 zone resets
    slat (usec): min=2, max=1210.1k, avg=191.73, stdev=2620.78
    clat (nsec): min=633, max=201793, avg=1228.79, stdev=1118.42
     lat (usec): min=2, max=1210.1k, avg=193.16, stdev=2620.95
    clat percentiles (nsec):
     |  1.00th=[  756],  5.00th=[  804], 10.00th=[  828], 20.00th=[  932],
     | 30.00th=[  996], 40.00th=[ 1012], 50.00th=[ 1032], 60.00th=[ 1048],
     | 70.00th=[ 1096], 80.00th=[ 1256], 90.00th=[ 1704], 95.00th=[ 2064],
     | 99.00th=[ 4128], 99.50th=[ 6688], 99.90th=[16192], 99.95th=[18560],
     | 99.99th=[27776]
   bw (  KiB/s): min= 2337, max=85032, per=100.00%, avg=41016.50, stdev=3789.15, samples=468
   iops        : min=  582, max=21258, avg=10253.91, stdev=947.31, samples=468
  lat (nsec)   : 750=0.98%, 1000=30.75%
  lat (usec)   : 2=42.40%, 4=23.76%, 10=1.61%, 20=0.45%, 50=0.06%
  lat (usec)   : 100=0.01%, 250=0.01%
  cpu          : usr=1.92%, sys=5.34%, ctx=812754, majf=1, minf=66
  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=602052,603252,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=39.2MiB/s (41.1MB/s), 39.2MiB/s-39.2MiB/s (41.1MB/s-41.1MB/s), io=2352MiB (2466MB), run=60002-60002msec
  WRITE: bw=39.3MiB/s (41.2MB/s), 39.3MiB/s-39.3MiB/s (41.2MB/s-41.2MB/s), io=2356MiB (2471MB), run=60002-60002msec

Disk stats (read/write):
    dm-0: ios=361023/500039, merge=0/0, ticks=47002/484395, in_queue=531397, util=99.83%, aggrios=361930/500891, aggrmerge=0/25630, aggrticks=47194/467630, aggrin_queue=514825, aggrutil=99.83%
  vda: ios=361930/500891, merge=0/25630, ticks=47194/467630, in_queue=514825, util=99.83%

输出报告

输出的报告解释:Interpreting the output

# read/write/trim:IOPS 是每秒执行的平均 I/O;BW 是平均带宽速率
  write: IOPS=10.1k, BW=39.3MiB/s (41.2MB/s)(2356MiB/60002msec); 0 zone resets
    # 提交延迟,min 是最小值,max 是最大值,avg 是平均值,stdev 是标准偏差
    slat (usec): min=2, max=1210.1k, avg=191.73, stdev=2620.78
    # 完成延迟,从提交到 I/O 部分完成的时间
    clat (nsec): min=633, max=201793, avg=1228.79, stdev=1118.42
    # 总延迟,这表示从 fio 创建 I/O 单元到 I/O 操作完成的时间。它是提交和完成延迟之和
     lat (usec): min=2, max=1210.1k, avg=193.16, stdev=2620.95
    clat percentiles (nsec):
     |  1.00th=[  756],  5.00th=[  804], 10.00th=[  828], 20.00th=[  932],
     | 30.00th=[  996], 40.00th=[ 1012], 50.00th=[ 1032], 60.00th=[ 1048],
     | 70.00th=[ 1096], 80.00th=[ 1256], 90.00th=[ 1704], 95.00th=[ 2064],
     | 99.00th=[ 4128], 99.50th=[ 6688], 99.90th=[16192], 99.95th=[18560],
     | 99.99th=[27776]
   # 基于离散间隔测量值的带宽统计信息
   bw (  KiB/s): min= 2337, max=85032, per=100.00%, avg=41016.50, stdev=3789.15, samples=468
   # 基于离散间隔测量值的 IOPS 统计信息
   iops        : min=  582, max=21258, avg=10253.91, stdev=947.31, samples=468
  # I/O 完成延迟的分布,这是从 I/O 离开 fio 到完成的时间
  lat (nsec)   : 750=0.98%, 1000=30.75%
  lat (usec)   : 2=42.40%, 4=23.76%, 10=1.61%, 20=0.45%, 50=0.06%
  lat (usec)   : 100=0.01%, 250=0.01%
  # CPU 使用率
  cpu          : usr=1.92%, sys=5.34%, ctx=812754, majf=1, minf=66
  # 作业生命周期内 I/O 深度的分布
  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 块数
     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=602052,603252,0,0 short=0,0,0,0 dropped=0,0,0,0
     # 这些值适用于 latency_target 和相关选项。启用这些选项时,本节介绍满足指定延迟目标所需的 I/O 深度。
     latency   : target=0, window=0, percentile=100.00%, depth=1

组统计信息

Run status group 0 (all jobs):
   READ: bw=39.2MiB/s (41.1MB/s), 39.2MiB/s-39.2MiB/s (41.1MB/s-41.1MB/s), io=2352MiB (2466MB), run=60002-60002msec
  WRITE: bw=39.3MiB/s (41.2MB/s), 39.3MiB/s-39.3MiB/s (41.2MB/s-41.2MB/s), io=2356MiB (2471MB), run=60002-60002msec
  • bw:此组中线程的聚合带宽,后跟此组中所有线程的最小和最大带宽。括号外的值是 2 的幂格式,括号内的值是 10 的幂格式的等效值
  • io:此组中所有线程执行的聚合 I/O。格式与 bw 相同
  • run:此组中线程的最小和最长运行时间

磁盘统计信息

Disk stats (read/write):
    dm-0: ios=361023/500039, merge=0/0, ticks=47002/484395, in_queue=531397, util=99.83%, aggrios=361930/500891, aggrmerge=0/25630, aggrticks=47194/467630, aggrin_queue=514825, aggrutil=99.83%
  vda: ios=361930/500891, merge=0/25630, ticks=47194/467630, in_queue=514825, util=99.83%
  • ios:所有组执行的 I/O 数
  • sectors:所有组传输的数据量(以 512 字节为单位)
  • merge:I/O 调度程序执行的合并数
  • ticks:我们让磁盘忙碌的时钟周期数
  • in_queue:在磁盘队列中花费的总时间
  • util:磁盘利用率。值为 100% 表示我们使磁盘始终处于繁忙状态,50% 表示磁盘有一半的时间处于空闲状态

环境变量的方式

Environment variables

主要也是和 job file 配合使用,这里就不多做演示了,可以直接看上面的官方文档链接

命令行的方式

Command line options

  • 以下内容和上面 job file 的是一样的
fio --name=randrw \
--ioengine=libaio \
--rw=randwrite \
--bs=4k \
--size=1G \
--numjobs=4 \
--runtime=60 \
--time_based \
--group_reporting \
--filename=/tmp/randrw_testfile
posted @ 2024-10-28 16:51  月巴左耳东  阅读(47)  评论(0编辑  收藏  举报