在Linux系统中,测试硬盘的性能一般使用fio工具实现,fio是Flexible I/O Tester的缩写。是一个常受欢迎的、用于测试存储性能的工具,而且还可以模拟多种不同的I/O模式和工作负载。

一般我们要测试一块硬盘的性能,一般需要进行随机写入测试、随机读取测试、顺序写入测试、顺序读取测试和混合读写测试这五步。


fio的使用

这个工具不是Linux发行版自带的,需要自己手动安装才行。

# ubuntusudo apt install fio# centossudo 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