在Linux系统中,测试硬盘的性能一般使用fio工具实现,fio是Flexible I/O Tester的缩写。是一个常受欢迎的、用于测试存储性能的工具,而且还可以模拟多种不同的I/O模式和工作负载。
一般我们要测试一块硬盘的性能,一般需要进行随机写入测试、随机读取测试、顺序写入测试、顺序读取测试和混合读写测试这五步。
fio的使用
这个工具不是Linux发行版自带的,需要自己手动安装才行。
# ubuntu
sudo apt install fio
# centos
sudo yum install fio
使用fio测试硬盘的写性能时,很容易就会造成系统上的数据丢失。主要就两种情况:
-
未指定文件名:不指定文件名会直接对硬盘进行测试。这样的操作将覆盖设备上的数据,包括文件系统、分区表等。这将导致整个设备上的数据丢失。
-
文件名重合:指定了文件名但与已存在的文件重合,写操作将会覆盖这个文件的内容,导致原有数据丢失。
随机写入性能测试
不绕过缓存
此时会受到会受到操作系统的页面缓存(page cache)的影响,即操作系统通常会缓存读写操作,这可能会导致不真实的高性能读写结果。使用直接I/O可以得到没有缓存效应的真实磁盘性能。
fio --name=testfile --directory=/home/ehigh/test_dir --size=1G --rw=randwrite --bs=4k --ioengine=libaio --iodepth=16 --numjobs=1 --runtime=30 --time_based --end_fsync=1
表示在 /home/ehigh/test_dir 目录中创建一个大小为1G的测试文件testfile,使用随机写入的模式进行测试,每次读/写的数据量是4KB。在30s的时间内,通过启动一个工作进程或线程来进行测试。
说明:
-
–name=testfile指定生成的测试文件名称,不指定就会会直接对硬盘进行测试,可能会造成数据丢失
-
–directory指定测试文件存放路径,不指定就是在当前路径下
-
–numjobs指定测试线程的数量,模拟单线程或单任务工作负载,不测试并发造成的额外压力,设置为1就可以了
-
–runtime指定测试时间,短时测试一般30s差不多了,可以快速评估和比较不同配置或硬件的性能
-
–size指定测试文件的大小,一般1G差不多就可以了
-
–rw指定测试的模式,andwrite是随机写入模式
-
–bs指定每个每个IO操作将使用4KB的大小
-
–end_fsync指定测试结束时,确保所有写入都同步到磁,这样更能确保测试数据的准确
write: IOPS=11.3k, BW=43.0MiB/s
# 在测试期间,平均每秒钟完成了11.3k次独立的IO写操作,这些写操作的总带宽是1825KiB每秒(即表示每秒钟的数据写入速度)
# slat:提交延迟 clat:完成延迟 lat:总延迟
# slat:指应用程序提交I/O到操作系统,到操作系统接收并开始处理这个I/O所需的时间。 平均的提交延迟为2.68微秒。
# clat:指操作系统开始处理I/O,到I/O操作真正完成所需的时间。完成延迟为1326.67微秒,即约1.326毫秒。
# lat:应用程序提交I/O到I/O操作真正完成所需的时间。这里的总延迟的标准偏差为167,993.51微秒,即约168毫秒
# clat percentiles (usec):不同百分位数下的完成延迟,可以通过这个来确定迟的分布
# 99.99th=[ 545] 如果99th百分位数的延迟远高于平均延迟(clat的avg值),这可能意味着存在一些异常高的延迟。
cpu:测试过程中用户空间和内核空间的CPU使用率,usr表示用户空间。sys表示内核空间
# 这个是写操作的摘要信息
Run status group 0 (all jobs):
WRITE: bw=43.0MiB/s (46.1MB/s), 43.0MiB/s-43.0MiB/s (46.1MB/s-46.1MB/s), io=2048MiB (2147MB), run=46558-46558msec
# bw=43.0MiB/s :平均带宽,每秒钟数据写入的速度
# io=2048MiB (2147MB): 在整个测试过程中写入的总数据量。
Disk stats (read/write):
sda: ios=2/7271, merge=0/348, ticks=1637/389056, in_queue=409371, util=95.63%
# ios=2/7271: 读/写的I/O操作数,进行了2次读操作和7271次写操作
# util=95.63%,测试过程中设备的利用率,接近100%的值通常意味着磁盘是瓶颈。
绕过缓存
通过 -direct=1 参数 在 fio 中用于启用直接I/O模式,数据直接从用户空间传输到磁盘,或从磁盘传输到用户空间,而不经过操作系统的缓存。
fio --name=testfile --directory=/home/ehigh/test_dir --size=1G --rw=randwrite --bs=4k --ioengine=libaio --iodepth=16 --numjobs=1 --runtime=30 --time_based --end_fsync=1 -direct=1
可以明显看到,绕过缓存后瞬间就降下来了。
多线程测试
–numjobs 参数在 fio 中用于指定测试中应使用的任务(线程或进程)数量,可以用来测试并发度,吞吐量、延迟等内容。
因为多个线程执行时,可能导致更高的 I/O 压力和更高的设备利用率、高延迟等。这样更加能模拟涉及到多线程或多进程并发访问存储的情况。
fio --name=testfile --directory=/home/ehigh/test_dir --size=1G --rw=randwrite --bs=4k --ioengine=libaio --iodepth=16 --numjobs=4 --runtime=30 --time_based --end_fsync=1 -direct=1
随机读取测试
fio --name=randread --directory=/home/ehigh/test_dir --size=1G --rw=randread --bs=4k --ioengine=libaio --iodepth=16 --numjobs=1 --runtime=30 --time_based --end_fsync=1
顺序写入测试
fio --name=seqwrite --directory=/home/ehigh/test_dir --size=1G --rw=write --bs=1M --ioengine=libaio --iodepth=16 --numjobs=1 --runtime=30 --time_based --end_fsync=1
顺序读取测试:
fio --name=seqread --directory=/home/ehigh/test_dir --size=1G --rw=read --bs=1M --ioengine=libaio --iodepth=16 --numjobs=1 --runtime=30 --time_based --end_fsync=1
混合读写测试
fio --name=mixedrw --rw=rw --rwmixread=70 --bs=4k --numjobs=1 --ioengine=libaio --iodepth=16 --runtime=60 --size=1G --filename=testfile --directory=/home/ehigh/test_dir