Linux下测量存储设备读/写性能的工具还是非常丰富的,例如我们下面要说的fio,还有dd,hdparm,ioping等等。本文我们主要说一下关于fio的使用。
关于fio
Fio 由 Jens Axboe 编写的一个开源I/O性能测试工具,它支持多种类型的I/O操作,包括顺序读写、随机读写等,可以模拟多种实际工作负载,用于评估存储设备的性能。
在管理 Linux 服务器时,尤其是在与数据库、虚拟化或任何 I/O 密集型任务相关的场景中,了解存储设备的性能至关重要。为此,fio是最可靠的工具之一 。此工具用途广泛,可以模拟各种 I/O 工作负载,以测试存储设备的性能。
“fio”可以在各种操作系统上使用,包括 Windows、macOS 和 FreeBSD等。但是,安装和使用可能因平台而异。
注意:
使用fio测试写性能时,如果直接向文件系统中写,会损坏电脑的分区,最终导致磁盘故障,所以记住:
1.不要使用fio向文件系统中测试读写,风险极高;
2.不要在生产服务器上测试任何不知道是否有风险的命令;
尽可能不要在系统分区做测试!!!!!!!!!!不要针对正在使用的设备运行具有写入的工作负载。
在使用fio进行测试过程中, filename参数指定某个要测试的裸设备(硬盘或分区),尽可能不在系统分区,这可能会破坏系统分区,而导致系统崩溃。
源代码
Fio 驻留在 git 存储库中,规范位置为:
格式fio-git-*.tar.gz
,包括 git 元数据也是如此。其他压缩包是官方 fio 版本的存档。 快照可从以下位置下载:
还有两个官方mirrors。可以安全地用作备份:
https://git.kernel.org/pub/scm/linux/kernel/git/axboe/fio.git
二进制包
Debian的:
从 Debian “Squeeze” 开始,fio 软件包是官方 Debian 仓库。https://packages.debian.org/search?keywords=fio .
Ubuntu的:
从 Ubuntu 10.04 LTS(又名“Lucid Lynx”)开始,fio 软件包是其中的一部分 Ubuntu “universe” 仓库。https://packages.ubuntu.com/search?keywords=fio .
Red Hat、Fedora、CentOS 等:
从 Fedora 9/Extra Packages for Enterprise Linux 4 开始,fio 软件包是 Fedora/EPEL 仓库的一部分。https://packages.fedoraproject.org/pkgs/fio/ .
windows:
从 fio 3.31 开始,标记版本的 Windows 安装程序是 可在 GitHub 上找到,网址为 https://github.com/axboe/fio/releases。这 Windows 的最新安装程序也可以作为 GitHub Actions 获取 通过从 https://github.com/axboe/fio/actions 中选择构建来创建工件。这些需要登录到 GitHub 帐户。
其他linux可以去官网查看。
安装“fio”
在运行任何测试之前,我们需要确保 fio 安装在我们的 Linux 机器上。
Ubuntu:
sudo apt-get update && sudo apt-get install fio -y
Oracle Linux 或 CentOS
sudo dnf install fio -y
sudo yum install fio -y
仓库中没有自行编译
tar -xzvf fio-x.x.x.tar.gz //下载压缩包并上传后,解压
cd fio-x.x.x
//自行编译
./configure
make
sudo make install
请注意,在以下平台上 GNU make 不是默认的,GNU make 是必需的。在 BSD 上,它可以从 devel/gmake 获得 ports 目录;在 Solaris 上,它位于 SUNWgmake 软件包中。
Configure 将打印启用的选项。请注意,在基于 Linux 的平台上, 必须安装 libaio 开发包才能使用。根据发行版的不同,它通常被称为 libaio-devel 或 libaio-dev。
对于 gfio,需要 gtk 2.18(或更高版本)、关联的 glib 线程和 cairo 要安装。GFIO不是自动构建的,可以通过配置选项进行启用。
要使用交叉编译器构建 fio:
$ make clean
$ make CROSS_COMPILE=/path/to/toolchain/prefix
Configure 将尝试自动确定目标平台。
也可以为 ESX 构建 fio,请使用 switch to 配置。--esx
windows下安装
如何在 64 位 Windows 上源码编译 fio:
- 安装 Cygwin (https://www.cygwin.com/)。安装 make 和 所有 以 mingw64-x86_64 开头的软件包。如果您愿意,请确保安装了 mingw64-x86_64-zlib 启用 fio 的日志压缩功能。
- 打开 Cygwin 终端。
- 进入 fio 目录(源文件)。
- run。
make clean && make -j
window下的直接安装,下载x64或32位已经编译好的安装文件。fio-x.xx-x64.msi或fio-x.xx-x86.msi。
下载后,双击安装。
安装完毕以后,在C:\Program Files\fio目录下找到fio.exe并双击,然后在当前目录下按住shift键,右键打开PowerShell,输入fio –version,出现版本信息,说明安装成功。
基本“fio”命令
要使用 fio 运行基本测试,请使用以下命令:
$ fio --name=test --ioengine=sync --rw=randwrite --bs=4k --numjobs=1 --size=1G --runtime=10m --time_based
以下是参数的细分:
- –name=test:将作业命名为“test”。
- –ioengine=sync:指定要使用的 I/O 引擎。
- –rw=randwrite:这会将 I/O 模式设置为随机写入。
- –bs=4k:这会将块大小设置为 4KB。
- –numjobs=1:这将运行一个作业/线程。
- –size=1G:这会将作业的 I/O 总大小设置为 1GB。
- –runtime=10m:这会将作业限制为 10 分钟。
- –time_based:这将使作业在指定时间内运行,而不考虑 I/O 的数量。
例如:
test: (g=0): rw=randwrite, bs=(R) 4096B-4096B, (W) 4096B-4096B, (T) 4096B-4096B, ioengine=sync, iodepth=1
fio-3.27
Starting 1 process
Jobs: 1 (f=1): [w(1)][100.0%][w=4056KiB/s][w=1014 IOPS][eta 00m:00s]
test: (groupid=0, jobs=1): err= 0: pid=12345: Fri Oct 13 10:10:10 2023
write: IOPS=1012, BW=4048KiB/s (4147kB/s)(600MiB/152022msec)
clat (usec): min=2, max=1058, avg= 4.66, stdev= 2.31
lat (usec): min=2, max=1058, avg= 4.68, stdev= 2.32
clat percentiles (usec):
| 1.00th=[ 3], 5.00th=[ 3], 10.00th=[ 3], 20.00th=[ 4],
| 30.00th=[ 4], 40.00th=[ 4], 50.00th=[ 4], 60.00th=[ 4],
| 70.00th=[ 4], 80.00th=[ 5], 90.00th=[ 5], 95.00th=[ 5],
| 99.00th=[ 6], 99.50th=[ 7], 99.90th=[ 11], 99.95th=[ 13],
| 99.99th=[ 21]
lat (usec) : 4=60.01%, 10=39.96%, 20=0.02%, 50=0.01%
cpu : usr=1.23%, sys=4.56%, ctx=154011, majf=0, minf=8
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,153600,0,0 short=153600,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=4048KiB/s (4147kB/s), 4048KiB/s-4048KiB/s (4147kB/s-4147kB/s), io=600MiB (629MB), run=152022-152022msec
Disk stats (read/write):
sda: ios=0/153594, merge=0/789, ticks=0/615, in_queue=615, util=0.40%
要测量读取和写入性能,可以调整 –rw 参数:
- 对于随机读取:–rw=randread
- 对于随机写入:–rw=randwrite
- 对于顺序读取:–rw=read
- 对于顺序写入:–rw=write
结果解读
测试完成后,fio 将提供详细的输出。需要注意的最重要的指标是:
1. 测试配置:
test: (g=0): rw=randwrite, bs=(R) 4096B-4096B, (W) 4096B-4096B, (T) 4096B-4096B, ioengine=sync, iodepth=1
- rw=randwrite:测试设置为执行随机写入。
- bs=(R) 4096B-4096B, (W) 4096B-4096B, (T) 4096B-4096B:读取、写入和总操作的块大小设置为 4KB。
- ioengine=sync:I/O 操作同步执行。
- iodepth=1:I/O 操作队列的深度设置为 1,表示一次处理一个操作。
2. 绩效指标:
write: IOPS=1012, BW=4048KiB/s (4147kB/s)(600MiB/152022msec)
- IOPS=1012:存储设备的 I/O 性能为每秒 1012 次输入/输出操作。
- BW=4048KiB/s (4147kB/s):带宽或数据传输速率约为 4048 KiB/s(或 4147 kB/s)。
- 600MiB/152022 毫秒:在 152,022 毫秒(或大约 152 秒)内总共写入了 600 MiB 的数据。
3. 延迟指标:
clat (usec): min=2, max=1058, avg= 4.66, stdev= 2.31
- clat (usec):这是指完成延迟,即完成 I/O 操作所需的时间。
- min=2,max=1058:最快的 I/O 操作需要 2 微秒,而最慢的 I/O 操作需要 1058 微秒。
- avg= 4.66:平均而言,I/O 操作大约需要 4.66 微秒。
- stdev= 2.31:衡量延迟可变性的标准差为 2.31 微秒。
4. 延迟百分位数:
百分位数提供对延迟值分布的见解。例如:
- 1.00th=[3]:1% 的 I/O 操作的延迟为 3 微秒或更短。
- 99.99th=[21]:99.99% 的 I/O 操作延迟为 21 微秒或更短。
5. CPU使用率:
cpu: usr=1.23%, sys=4.56%, ctx=154011, majf=0, minf=8
- usr=1.23%:在测试期间,1.23% 的 CPU 用于用户级进程。
- sys=4.56%:4.56% 的 CPU 用于系统级进程。
- ctx=154011:测试期间发生的上下文切换次数。
- majf=0, minf=8:主要和次要页面错误。当必须从磁盘检索数据时(不理想),就会发生重大故障,而次要故障会检索内存中其他位置的数据。
6. 磁盘统计:
sda: ios=0/153594, merge=0/789, ticks=0/615, in_queue=615, util=0.40%
- ios=0/153594:在 sda 磁盘上没有读取操作 (ios=0),执行了 153,594 次写入操作。
- merge=0/789:未发生读取合并,发生 789 次写入合并。合并是指在处理之前合并的操作。
- ticks=0/615:读取和写入所花费的时间。在本例中,写入花费了 615 毫秒。
- in_queue=615:操作排队的总时间。
- util=0.40%:测试期间的磁盘利用率。
FIO 命令分解执行
IOPS 性能测试
测试随机读取
sudo fio --filename=device name --direct=1 --rw=randread --bs=4k --ioengine=libaio --iodepth=256 --runtime=120 --numjobs=4 --time_based --group_reporting --name=iops-test-job --eta-newline=1 --readonly
在某些情况下,如果使用作业文件而不是直接运行命令,可能会看到更一致的结果。对于此方法,请使用以下步骤。
使用以下内容创建作业文件 fiorandomread.fio:
[global]
bs=4K
iodepth=256
direct=1
ioengine=libaio
group_reporting
time_based
runtime=120
numjobs=4
name=raw-randread
rw=randread
[job1]
filename=device name
使用以下命令运行作业:
fio randomread.fio
测试文件随机读/写
对挂载点运行以下命令以测试文件读/写:
sudo fio --filename=/custom mount point/file --size=500GB --direct=1 --rw=randrw --bs=4k --ioengine=libaio --iodepth=256 --runtime=120 --numjobs=4 --time_based --group_reporting --name=iops-test-job --eta-newline=1
测试随机读/写
不要直接针对正在使用的设备运行具有写入工作负载 (readwrite
randrw
write
trimwrite
) 的 FIO 测试
执行以下命令,测试随机读/写操作。
sudo fio --filename=device name --direct=1 --rw=randrw --bs=4k --ioengine=libaio --iodepth=256 --runtime=120 --numjobs=4 --time_based --group_reporting --name=iops-test-job --eta-newline=1
在某些情况下,如果使用作业文件而不是直接运行命令,可能会看到更一致的结果。对于此方法,请使用以下步骤。
使用以下内容创建作业文件 fiorandomreadwrite.fio:
[global]
bs=4K
iodepth=256
direct=1
ioengine=libaio
group_reporting
time_based
runtime=120
numjobs=4
name=raw-randreadwrite
rw=randrw
[job1]
filename=device name
使用以下命令运行作业:
fio randomreadwrite.fio
测试顺序读
对于使您能够利用顺序访问模式的工作负载(如数据库工作负载),可以通过测试顺序读取来确认此模式的性能。
sudo fio --filename=device name --direct=1 --rw=read --bs=4k --ioengine=libaio --iodepth=256 --runtime=120 --numjobs=4 --time_based --group_reporting --name=iops-test-job --eta-newline=1 --readonly
在某些情况下,如果使用作业文件而不是直接运行命令,可能会看到更一致的结果。对于此方法,请使用以下说明:
使用以下内容创建作业文件 fioread.fio:
[global]
bs=4K
iodepth=256
direct=1
ioengine=libaio
group_reporting
time_based
runtime=120
numjobs=4
name=raw-read
rw=read
[job1]
filename=device name
使用以下命令运行作业:
fio read.fio
吞吐量性能测试
使用以下 FIO 示例命令测试吞吐量性能。
测试随机读取
sudo fio --filename=device name --direct=1 --rw=randread --bs=256k --ioengine=libaio --iodepth=64 --runtime=120 --numjobs=4 --time_based --group_reporting --name=throughput-test-job --eta-newline=1 --readonly
测试文件随机读/写
sudo fio --filename=/custom mount point/file --size=500GB --direct=1 --rw=randrw --bs=64k --ioengine=libaio --iodepth=64 --runtime=120 --numjobs=4 --time_based --group_reporting --name=throughput-test-job --eta-newline=1
测试随机读/写
不要直接针对正在使用的设备运行具有写入工作负载 (readwrite
randrw
write
trimwrite
) 的 FIO 测试
sudo fio --filename=device name --direct=1 --rw=randrw --bs=256k --ioengine=libaio --iodepth=64 --runtime=120 --numjobs=4 --time_based --group_reporting --name=throughput-test-job --eta-newline=1
测试顺序读取
sudo fio --filename=device name --direct=1 --rw=read --bs=256k --ioengine=libaio --iodepth=64 --runtime=120 --numjobs=4 --time_based --group_reporting --name=throughput-test-job --eta-newline=1 --readonly
延迟性能测试
测试随机读取的延迟
sudo fio --filename=device name --direct=1 --rw=randread --bs=4k --ioengine=libaio --iodepth=1 --numjobs=1 --time_based --group_reporting --name=readlatency-test-job --runtime=120 --eta-newline=1 --readonly
在某些情况下,如果使用作业文件而不是直接运行命令,可能会看到更一致的结果。对于此方法,请使用以下步骤。
使用以下内容创建作业文件 fiorandomreadlatency.fio:
[global]
bs=4K
iodepth=1
direct=1
ioengine=libaio
group_reporting
time_based
runtime=120
numjobs=1
name=readlatency-test-job
rw=randread
[job1]
filename=device name
使用以下命令运行作业:
fio fiorandomreadlatency.fio
测试随机读/写延迟
不要直接针对正在使用的设备运行具有写入工作负载 (readwrite
randrw
write
trimwrite
) 的 FIO 测试
sudo fio --filename=device name --direct=1 --rw=randrw --bs=4k --ioengine=libaio --iodepth=1 --numjobs=1 --time_based --group_reporting --name=rwlatency-test-job --runtime=120 --eta-newline=1
在某些情况下,如果使用作业文件而不是直接运行命令,可能会看到更一致的结果。对于此方法,请使用以下步骤。
使用以下内容创建作业文件 fiorandomrwlatency.fio:
[global]
bs=4K
iodepth=1
direct=1
ioengine=libaio
group_reporting
time_based
runtime=120
numjobs=1
name=rwlatency-test-job
rw=randrw
[job1]
filename=device name
使用以下命令运行作业:
fio fioradomrwlatency.fio
错误的命令会损坏系统
错误的使用fio测试随机读的命令:
# 错误原因主要是-filename=/dev/mapper/centos-root,不应当适用-filename制定磁盘的文件系统名称,而是应当在要测试的磁盘中创建一个目录,指定为该目录下的一个文件
fio -name=test -filename=/dev/mapper/centos-root -direct=1 -iodepth=20 -thread -rw=randread -ioengine=libaio -bs=16k -size=1G -numjobs=2 -runtime=300 -group_reporting
错误的使用fio测试随机写的命令:
# 错误原因是不应当使用 -filename=/dev/mapper/centos-root指定文件系统的名称,这样会损坏文件系统的分区
fio -name=test -filename=/dev/mapper/centos-root -direct=1 -iodepth=20 -thread -rw=randwrite -ioengine=libaio -bs=16k -size=1G -numjobs=2 -runtime=300 -group_reporting -allow_mounted_write=1
正确的使用fio测试随机读的命令:
# 这样会操作/home目录下的test文件,不会影响文件系统
fio -name=test -filename=/home/test -direct=1 -iodepth=20 -thread -rw=randread -ioengine=libaio -bs=16k -size=1G -numjobs=2 -runtime=300 -group_reporting
正确的使用fio测试随机写的命令:
# 这样会随机写/home下面的test文件,不会对文件系统产生任何影响,也不会导致磁盘故障和格式化重装
fio -name=test -filename=/home/test -direct=1 -iodepth=20 -thread -rw=randwrite -ioengine=libaio -bs=16k -size=1G -numjobs=2 -runtime=300 -group_reporting -allow_mounted_write=1