[TOC]
linux存储测试
在考虑测试存储的稳定性和进行压力测试时,fio 通常被认为是最合适的工具。具体如下:
-
fio:
- 灵活性:fio提供了强大的配置选项,允许用户自定义测试场景,包括读写比例、IOPS(每秒输入/输出操作数)、并发线程数等。
- 详细报告:fio在测试完成后提供详细的性能报告,包括延迟、吞吐量和IO操作的分布情况。
- 模拟真实场景:fio能够模拟真实的工作负载,通过创建接近实际应用场景的测试来评估存储系统的性能。
- 压力测试:fio可以模拟高负载情况下的存储性能,帮助发现在极端条件下的性能瓶颈和稳定性问题。
-
dd:
- 简单直接:dd是一个简单直接的磁盘I/O测试工具,通常用于快速检查磁盘的读写速度。
- 数据复制:dd主要用于数据复制,而不是专门设计来进行复杂的性能测试。
- 硬盘损害:频繁使用dd进行测试可能对硬盘造成损害,因此不建议多次或长时间运行。
-
hdparm:
- 简单性能检测:hdparm是一个用于测试磁盘性能的简单工具,它可以快速检测硬盘的读写性能。
- 功能有限:相比fio,hdparm的功能较为有限,不适合进行复杂的压力测试。
-
unixbench:
- 综合性能评估:unixbench是一个综合的性能测试工具,它包含了多个测试用例,不仅限于存储性能。
- 不够灵活:虽然unixbench可以提供一些关于存储性能的数据,但它不如fio那样灵活和详细。
FIO安装
-
使用包管理器安装(推荐):
-
对于 Debian/Ubuntu 等系统,可以使用以下命令安装:
sudo apt-get update sudo apt-get install fio
-
对于 CentOS/RHEL 等系统,可以使用以下命令安装:
sudo yum install fio
-
-
从源代码构建:
如果您希望使用最新版本的
fio
或者无法使用包管理器安装,可以从源代码构建:git clone https://github.com/axboe/fio.git cd fio ./configure make sudo make install
-
验证安装:
安装完成后,您可以通过运行以下命令来验证
fio
是否成功安装:fio --version
安装完成后,您就可以在命令行中使用 fio
命令来进行磁盘 I/O 性能测试。
FIO使用
要使用 fio
进行磁盘 I/O 性能测试,您可以按照以下基本步骤进行配置和执行测试:
-
创建配置文件:
创建一个包含测试参数的配置文件,通常以
.fio
扩展名结尾。例如,您可以创建一个名为test.fio
的文件,并在其中指定测试参数,如测试类型、块大小、混合读写比例等。以下是一个简单的示例配置文件:[global] ioengine=libaio directory=/path/to/test/directory [job] rw=readwrite size=1G bs=4k numjobs=4 runtime=30s """ #[global] 部分定义了全局配置选项,应用于整个测试任务。 #ioengine=libaio:指定使用 libaio 引擎进行异步 I/O 操作。libaio 是 Linux 中用于异步 I/O 的库。 #directory=/path/to/test/directory:指定测试文件的目录路径。fio 将在这个目录中创建测试文件并执行 I/O 操作。 #[job] 部分定义了一个具体的测试任务。 #rw=readwrite:指定测试类型为读写混合。 #size=1G:指定每个作业(job)的文件大小为 1GB。fio 将在测试开始时创建一个大小为 1GB 的测试文件。 #bs=4k:指定每次 I/O 操作的块大小为 4KB。这决定了每个读取或写入操作涉及多少数据。 #创建 4 个并发作业,每个作业读取 1GB 的数据,运行时间为 30 秒。 """
-
运行测试:
在终端中使用
fio
命令来运行测试,指定配置文件的路径作为参数。例如,要运行名为test.fio
的配置文件中定义的测试,可以执行以下命令:fio test.fio fio test.fio --output-format=json --output=result.json #运行测试并将结果以 JSON 格式保存在 result.json 文件中
-
查看结果:
fio
将执行配置文件中定义的测试,并在测试完成后显示结果。您可以查看吞吐量、IOPS、延迟等性能指标,以及其他有关测试执行的详细信息。
附录(指标示例及分析说明)
结果示例
//result.json
{
"fio version": "fio-3.28",
"timestamp": 1644631415,
"timestamp_ms": 1644631415137,
"time": "Wed Feb 12 14:03:35 2022",
"jobs": [
{
"jobname": "Seq-read",
"groupid": 0,
"error": 0,
"read": {
"io_bytes": 1073741824,
"bw": 428284,
"iops": 107071,
"runtime": 2504,
"total_ios": 26819,
"short_ios": 0,
"drop_ios": 0
},
"write": {
"io_bytes": 0,
"bw": 0,
"iops": 0,
"runtime": 2504,
"total_ios": 0,
"short_ios": 0,
"drop_ios": 0
},
"trim": {
"io_bytes": 0,
"bw": 0,
"iops": 0,
"runtime": 0,
"total_ios": 0,
"short_ios": 0,
"drop_ios": 0
},
"runt": 2,
"lat": {
"min": 2836,
"max": 183752,
"mean": 18643,
"stddev": 11079,
"pct95": 32059,
"pct99": 40071
},
"bw_min": 354856,
"bw_max": 466240,
"bw_agg": 100.00,
"bw_mean": 428284.00,
"bw_dev": 7.68,
"bw_samples": 59,
"iops_min": 88714,
"iops_max": 116560,
"iops_mean": 107071.20,
"iops_stddev": 1.54,
"iops_samples": 59,
"cpu_user": 0.29,
"cpu_sys": 2.43,
"cpu_csw": 423971,
"cpu_migrate": 30,
"cpu_run": 12512,
"cpu_idle": 236000
}
],
"disk_util": {
"sda": 5.18
}
}
分析示例
示例 result.json 文件,包含了一个名为 "Seq-read" 的作业的性能指标数据。下面是对其中一些关键指标的分析结果:
-
吞吐量(Throughput):
- "bw": 428284,单位为 KB/s,表示读取操作的带宽,约为 418.48 MB/s。
- "bw_agg": 100.00,表示带宽的聚合百分比,表示没有发生数据丢失或短操作。
-
IOPS(每秒 I/O 操作数):
- "iops_mean": 107071.20,表示平均每秒读取操作数。
-
延迟(Latency):
- "lat": { "mean": 18643,单位为微秒,表示平均读取延迟,约为 18.64 毫秒。 "pct95": 32059,表示 95% 的读取操作的延迟小于等于 32.06 毫秒。 "pct99": 40071,表示 99% 的读取操作的延迟小于等于 40.07 毫秒。 }
-
CPU 使用情况:
- "cpu_user": 0.29,表示用户空间 CPU 使用率。
- "cpu_sys": 2.43,表示内核空间 CPU 使用率。
- "cpu_csw": 423971,表示上下文切换次数。
- "cpu_migrate": 30,表示进程迁移次数。
- "cpu_run": 12512,表示进程在运行状态的时间。
- "cpu_idle": 236000,表示 CPU 空闲时间。
-
磁盘利用率:
- "disk_util": {"sda": 5.18},表示磁盘利用率为 5.18%。
配置文件示例
[global]
ioengine=libaio
#设置 ioengine 参数为 sync,表示使用同步 I/O 模式
direct=1
#可以配置为 direct=0,表示不使用直接 I/O 模式,而是使用系统缓存。这样可以模拟实际应用中对系统缓存的利用情况
thread=1
#可以配置为 thread=0,表示不使用多线程模式,而是使用单线程。这样可以测试单线程下的性能表现。
iodepth=32
#可以配置为其他数值,如 iodepth=1,表示每个作业的 I/O 队列深度为 1。较小的队列深度可能会导致更低的并发性能
group_reporting
#可以省略该选项,不使用合并报告。在某些情况下,单独报告每个作业的统计数据可能更有用。
time_based
#可以配置为 time_based=0,表示不基于时间运行测试,而是基于数据量或操作次数运行测试。
[job]
name=randread
rw=randread
directory=/path/to/test/directory
size=1G
bs=4k
numjobs=4
runtime=30s
说明:
-
[global]
部分定义了全局配置选项,应用于整个测试任务。-
ioengine=libaio
:指定使用libaio
引擎进行异步 I/O 操作。 -
direct=1
:表示使用直接 I/O 模式,跳过系统缓存。 -
thread=1
:使用多线程模式。 -
iodepth=32
:每个作业的 I/O 队列深度为 32。 -
group_reporting
:将多个作业的统计数据合并报告。 -
time_based
:基于时间运行测试。
-
-
[job]
部分定义了一个具体的测试任务。-
name=randread
:作业名称。 -
rw=randread
:指定测试类型为随机读取。 -
directory=/path/to/test/directory
:指定测试文件的目录路径。 -
size=1G
:指定每个作业(job)的文件大小为 1GB。 -
bs=4k
:指定每次 I/O 操作的块大小为 4KB。 -
numjobs=4
:指定并发作业数为 4。 -
runtime=30s
:指定测试运行时间为 30 秒。
-
RW参数说明:
参数类型
rw
参数还支持以下几种配置类型,每种类型对应不同的 I/O 操作模式:
- randwrite:随机写入。在测试中,fio 将会在文件内随机选择位置进行写操作。
- randrw:随机读写混合。这个配置同时包含了随机读取和随机写入操作。可以用来模拟同时有读写操作的场景。
- read:顺序读取。在测试中,fio 将会按照顺序从文件中读取数据。
- write:顺序写入。在测试中,fio 将会按照顺序向文件中写入数据。
不同配置类型适用于不同的应用场景:
- 随机读取 (
randread
):适用于模拟数据库或文件系统等需要频繁随机读取操作的场景。 - 随机写入 (
randwrite
):适用于模拟日志写入或其他需要频繁随机写入操作的场景。 - 顺序读取 (
read
):适用于需要连续读取大量数据的场景,如视频播放。 - 顺序写入 (
write
):适用于需要连续写入大量数据的场景,如备份操作。
其他测试类型
-
基于数据量运行测试:
- 设置
size
参数为所需的文件大小,例如size=1G
表示每个作业(job)的文件大小为 1GB。 - 设置
filesize
参数为文件大小,例如filesize=1G
表示每个文件的大小为 1GB。 - 设置
nrfiles
参数为文件数量,例如nrfiles=4
表示要创建 4 个文件。
示例配置:
[job] rw=randread size=1G bs=4k numjobs=4 runtime=30s
- 设置
-
基于操作次数运行测试:
- 设置
io_size
参数为每次 I/O 操作的大小,例如io_size=4k
表示每次操作读取或写入 4KB 的数据。 - 设置
size
参数为操作次数乘以每次操作的大小,例如size=4000
表示总共执行 4000 次操作,每次操作读取或写入 4KB 的数据。 - 设置
ioengine
参数为sync
,表示使用同步 I/O 模式。
示例配置:s
[global] ioengine=sync [job] rw=randread io_size=4k size=4000 numjobs=4 runtime=30s
- 设置