网站Logo GESONG

Linux硬盘性能测试工具-FIO

gesong
0
2025-09-11

1.硬盘I/O测试类型

    在日常测试中,硬盘I/O测试类型主要有以下几种类型

  • 随机读、随机写、随机读写

  • 顺序读、顺序写、顺序读写

2.FIO介绍

    FIL是Linux中开源的一款IOPS测试工具,主要用来对硬盘进行压力测试和性能验证。使用FIO可以产生多线程或进程来执行特定类型的I/O操作,通过编写配置文件或直接命令行去执行测试动作,相当于是一个多线程的IO生成工具。使用FIO工具可生成多种IO模式来测试硬盘设备性能。其开源地址为:https://github.com/axboe/fio

使用FIO工具,可根据测试需求设置读写比例等,例如80%读,20%写等等

2.1 FIO安装

    以Ubuntu 22.04为例,安装命令如下所示:

sudo apt-get update && sudo apt-get install -y fio

2.2 常用参数

参数名

功能

取值示例

bs

定义I/O的块大小(block size),单位是k、K、m和M等,默认I/O块大小为4KB

4KB

ioengine

定义fio如何下发I/O请求,通常有同步I/O和异步I/O
- 同步I/O一次只能发出一个I/O请求,等待内核完成后才返回。这样对于单个线程I/O队列深度总是小于1,但是可以透过多个线程并发执行来解决。通常会用16~32个线程同时工作把I/O队列深度塞满
- 异步I/O则通常使用libaio这样的方式一次提交一批I/O请求,然后等待一批的完成,减少交互的次数,会更有效率

libaio

iodepth

定义测试时的I/O队列深度,默认为1

1

direct

direct模式
- 1:表示使用direct I/O,忽略 I/O 缓存,数据直写
- 0:表示使用buffered I/O
- 默认为True

1

rw

读写模式,可取的值
- 顺序读:read
- 顺序写:write
- 随机读:randread
- 随机写:randwrite
- 混合随机读写:randrw
- 混合顺序读写:readwrite

read

time_based

指定采用时间模式。无需设置该参数值,只要 FIO 基于时间来运行

runtime

指定测试时长,即 FIO 运行时长,以秒为单位

600

refill_buffers

FIO 将在每次提交时重新填充 I/O 缓冲区,默认设置是仅在初始时填充并重用该数据

norandommap

在进行随机 I/O 时,FIO 将覆盖文件的每个块,若给出此参数,则将选择新的偏移量而不查看 I/O 历史记录

randrepeat

随机序列是否可重复
- True或1:表示随机序列可重复
- False或0:表示随机序列不可重复
- 默认为 True

1

group_reporting

定义测试结果显示模式,group_reporting 表示汇总每个进程的统计信息,而非以不同job汇总展示信息

name

定义测试任务名称

filename

定义测试文件/设备的名称

/dev/vdb

size

定义测试I/O操作的数据量,如果未指定runtime这类参数,fio会将指定大小的数据量全部读/写完成,然后才停止测试。
- 该参数的值,可以是带单位的数字,比如size=10G,表示读/写的数据量为10GB;也可是百分数,比如size=20%,表示读/写的数据量占该设备总文件的20%的空间

500GB

rwmixwrite

在混合读写的模式下,写占比

30

numjobs

定义测试的并发线程数

2.3 FIO使用

2.3.1 以命令行方式运行

  • 测试随机写IOPS

sudo fio -direct=1 -iodepth=32 -rw=randwrite -ioengine=libaio -bs=4k -size=20G -numjobs=16 -runtime=600 -group_reporting -filename=/${MOUNT_PATH}}$/${TEST_FILE_NAME} -name={RAND_WRITE_TEST}
  • 测试随机读IOPS

sudo  -direct=1 -iodepth=32 -rw=randread -ioengine=libaio -bs=4k -size=20G -numjobs=16 -runtime=600 -group_reporting -filename=/dev/{DEVICE_NAME} -name={RAND_READ_TEST}
  • 测试写吞吐量

sudo fio -direct=1 -iodepth=64 -rw=write -ioengine=libaio -bs=4k -size=20G -numjobs=16 -runtime=600 -group_reporting -filename=/${MOUNT_PATH}}$/${TEST_FILE_NAME} -name={WRITE_TEST}
  • 测试读吞吐量

sudo fio -direct=1 -iodepth=64 -rw=read -ioengine=libaio -bs=4k -size=20G -numjobs=16 -runtime=600 -group_reporting -filename=/dev/{DEVICE_NAME} -name={READ_TEST}

2.4 结果分析

# sudo fio fio.conf
rand-read-test: (g=0): rw=randread, bs=(R) 4096B-4096B, (W) 4096B-4096B, (T) 4096B-4096B, ioengine=libaio, iodepth=1
...
rand-write-test: (g=0): rw=randwrite, bs=(R) 4096B-4096B, (W) 4096B-4096B, (T) 4096B-4096B, ioengine=libaio, iodepth=1
...
rand-read-write-test: (g=0): rw=randrw, bs=(R) 4096B-4096B, (W) 4096B-4096B, (T) 4096B-4096B, ioengine=libaio, iodepth=1
...
fio-3.28
Starting 96 processes
Jobs: 96 (f=96): [r(32),w(32),m(32)][100.0%][r=151MiB/s,w=104MiB/s][r=38.6k,w=26.7k IOPS][eta 00m:00s]
rand-read-test: (groupid=0, jobs=96): err= 0: pid=3058638: Wed Aug 20 10:47:05 2025
  read: IOPS=41.0k, BW=160MiB/s (168MB/s)(18.8GiB/120002msec)
    slat (usec): min=2, max=84346, avg=237.56, stdev=917.90
    clat (nsec): min=882, max=105729k, avg=934390.79, stdev=2021217.42
     lat (usec): min=3, max=110005, avg=1172.49, stdev=2263.52
    clat percentiles (usec):
     |  1.00th=[    3],  5.00th=[  184], 10.00th=[  285], 20.00th=[  404],
     | 30.00th=[  490], 40.00th=[  578], 50.00th=[  685], 60.00th=[  832],
     | 70.00th=[ 1020], 80.00th=[ 1254], 90.00th=[ 1598], 95.00th=[ 1893],
     | 99.00th=[ 2966], 99.50th=[ 5997], 99.90th=[28705], 99.95th=[50594],
     | 99.99th=[77071]
   bw (  KiB/s): min=93770, max=203572, per=100.00%, avg=164165.63, stdev=311.35, samples=15296
   iops        : min=23442, max=50892, avg=41034.97, stdev=77.90, samples=15296
  write: IOPS=25.6k, BW=99.9MiB/s (105MB/s)(11.7GiB/120002msec); 0 zone resets
    slat (usec): min=6, max=99557, avg=865.97, stdev=1946.04
    clat (nsec): min=1438, max=97151k, avg=997772.53, stdev=1607120.25
     lat (usec): min=56, max=105108, avg=1864.40, stdev=2650.19
    clat percentiles (usec):
     |  1.00th=[  161],  5.00th=[  285], 10.00th=[  371], 20.00th=[  498],
     | 30.00th=[  603], 40.00th=[  701], 50.00th=[  807], 60.00th=[  922],
     | 70.00th=[ 1057], 80.00th=[ 1237], 90.00th=[ 1598], 95.00th=[ 2040],
     | 99.00th=[ 3490], 99.50th=[ 5407], 99.90th=[20841], 99.95th=[33162],
     | 99.99th=[64750]
   bw (  KiB/s): min=52498, max=131745, per=100.00%, avg=102401.73, stdev=240.76, samples=15296
   iops        : min=13117, max=32932, avg=25595.54, stdev=60.25, samples=15296
  lat (nsec)   : 1000=0.01%
  lat (usec)   : 2=0.55%, 4=0.68%, 10=0.15%, 20=0.01%, 50=0.01%
  lat (usec)   : 100=0.27%, 250=4.76%, 500=20.56%, 750=23.99%, 1000=16.98%
  lat (msec)   : 2=27.58%, 4=3.76%, 10=0.37%, 20=0.13%, 50=0.13%
  lat (msec)   : 100=0.04%, 250=0.01%
  cpu          : usr=0.89%, sys=3.70%, ctx=13650352, majf=0, minf=6861
  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=4917306,3068451,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=160MiB/s (168MB/s), 160MiB/s-160MiB/s (168MB/s-168MB/s), io=18.8GiB (20.1GB), run=120002-120002msec
  WRITE: bw=99.9MiB/s (105MB/s), 99.9MiB/s-99.9MiB/s (105MB/s-105MB/s), io=11.7GiB (12.6GB), run=120002-120002msec

Disk stats (read/write):
  sde: ios=4798086/3074895, merge=44/137845, ticks=4552421/2533315, in_queue=7085984, util=99.97%

    每个执行任务的数据方向的I/O统计数据

  • IOPS 相关指标可以查看IOPS=***内容

  • 吞吐量相关指标可以查看BW=***内容

  • 时延相关指标可以查看lat相关内容

  • 提交延迟相关指标可以查看slat相关内容

  • 完成延迟相关指标可以查看clat相关内容

  • CPU使用率相关指标可以查看CPU相关内容

  • IO depths表示I/O在作业生命周期中的分布

    Run status group x 代表值含义

  • bw: 总带宽以及最小和最大带宽

  • io: 该组中所有线程执行的累计I/O

  • run: 这组线程中最小和最长的运行时。

    Disk stats 代表值含义

  • ios:所有组的I/O个数

  • merge:I/O调度器执行的总合并数

  • ticks:使磁盘繁忙的滴答数

  • in_queue:在磁盘队列中花费的总时间

  • util:磁盘利用率。

动物装饰