本章节在Linux实例中使用FIO工具测试块存储性能,包括IOPS、吞吐量、时延等。

前提条件

您已经创建了待测试的块存储,并将块存储挂载到ECS实例上。
说明 如果您只需测试某类型块存储的性能,建议您在新建的按量付费数据盘上测试性能,完成测试后可以随时释放。

背景信息

不同工具测试的硬盘基准性能会有差异,如ddsysbenchiometer等工具可能会受到测试参数配置和文件系统影响,难以反映真实性能。本示例的性能参数,均为Linux系统下采用FIO工具的测试结果,以此作为块存储产品性能指标参考。Linux实例和Windows实例都推荐使用FIO工具测试块存储性能。

警告 测试裸盘可以获得真实的块存储盘性能,但直接测试裸盘会破坏文件系统结构,请在测试前提前做好数据备份。具体操作,请参见创建普通快照。建议您只在新购无数据的ECS实例上使用工具测试块存储性能,避免造成数据丢失。

操作步骤

  1. 远程连接ECS实例。连接方式请参见通过VNC远程连接Linux实例
  2. 查询块存储设备是否已经4KiB对齐。
    sudo fdisk -lu
    返回的结果中,Start值能被8整除即是4KiB对齐。否则,请完成4KiB对齐后再继续性能测试。
    Device     Boot Start      End  Sectors Size Id Type
    /dev/vda1  *     2048 83886046 83883999  40G 83 Linux
  3. 依次运行以下命令安装libaio和FIO。
    sudo yum install libaio -y
    sudo yum install libaio-devel -y
    sudo yum install fio -y
  4. 切换路径。
    cd /tmp
  5. 运行性能测试命令,具体的命令请参见下文。

云盘性能测试命令

有关ESSD云盘的IOPS测试方法,请参见压测ESSD云盘IOPS性能

  • 随机写IOPS:
    fio -direct=1 -iodepth=128 -rw=randwrite -ioengine=libaio -bs=4k -size=1G -numjobs=1 -runtime=1000 -group_reporting -filename=iotest -name=Rand_Write_Testing
  • 随机读IOPS:
    fio -direct=1 -iodepth=128 -rw=randread -ioengine=libaio -bs=4k -size=1G -numjobs=1 -runtime=1000 -group_reporting -filename=iotest -name=Rand_Read_Testing
  • 顺序写吞吐量(写带宽):
    fio -direct=1 -iodepth=64 -rw=write -ioengine=libaio -bs=1024k -size=1G -numjobs=1 -runtime=1000 -group_reporting -filename=iotest -name=Write_PPS_Testing
  • 顺序读吞吐量(读带宽):
    fio -direct=1 -iodepth=64 -rw=read -ioengine=libaio -bs=1024k -size=1G -numjobs=1 -runtime=1000 -group_reporting -filename=iotest -name=Read_PPS_Testing
  • 随机写时延:
    fio -direct=1 -iodepth=1 -rw=randwrite -ioengine=libaio -bs=4k -size=1G -numjobs=1 -group_reporting -filename=iotest -name=Rand_Write_Latency_Testing
  • 随机读时延:
    fio -direct=1 -iodepth=1 -rw=randread -ioengine=libaio -bs=4k -size=1G -numjobs=1 -group_reporting -filename=iotest -name=Rand_Read_Latency_Testing

本地盘性能测试命令

以下测试命令仅适用于NVMe SSD本地盘。

  • 随机写IOPS:
    fio -direct=1 -iodepth=32 -rw=randwrite -ioengine=libaio -bs=4k -numjobs=4 -time_based=1 -runtime=1000 -group_reporting -filename=/dev/vdx -name=test
  • 随机读IOPS:
    fio -direct=1 -iodepth=32 -rw=randread -ioengine=libaio -bs=4k -numjobs=4 -time_based=1 -runtime=1000 -group_reporting -filename=/dev/vdx -name=test
  • 顺序写吞吐量(写带宽):
    fio -direct=1 -iodepth=128 -rw=write -ioengine=libaio -bs=128k -numjobs=1 -time_based=1 -runtime=1000 -group_reporting -filename=/dev/vdx -name=test
  • 顺序读吞吐量(读带宽):
    fio -direct=1 -iodepth=128 -rw=read -ioengine=libaio -bs=128k -numjobs=1 -time_based=1 -runtime=1000 -group_reporting -filename=/dev/vdx -name=test
  • 随机写延迟:
    fio -direct=1 -iodepth=1 -rw=randwrite -ioengine=libaio -bs=4k -numjobs=1 -time_based=1 -runtime=1000 -group_reporting -filename=/dev/vdx -name=test
  • 随机读延迟:
    fio -direct=1 -iodepth=1 -rw=randread -ioengine=libaio -bs=4k -numjobs=1 -time_based=1 -runtime=1000 -group_reporting -filename=/dev/vdx -name=test
  • 顺序写延迟:
    fio -direct=1 -iodepth=1 -rw=write -ioengine=libaio -bs=4k -numjobs=1 -time_based=1 -runtime=1000 -group_reporting -filename=/dev/vdx -name=test
  • 顺序读延迟:
    fio -direct=1 -iodepth=1 -rw=read -ioengine=libaio -bs=4k -numjobs=1 -time_based=1 -runtime=1000 -group_reporting -filename=/dev/vdx -name=test

共享块存储测试命令

所有ECS实例的iodepth取值总计不能超过384。例如,假设有四台实例同时压测,则每台实例iodepth取值至少小于等于96

  • 两台ECS实例参与压测时(取iodepth=128):
    • 随机写IOPS
      fio -direct=1 -iodepth=128 -rw=randwrite -ioengine=libaio -bs=4k -size=1G -numjobs=1 -runtime=1000 -group_reporting -filename=iotest -name=Rand_Write_Testing
    • 随机读IOPS
      fio -direct=1 -iodepth=128 -rw=randread -ioengine=libaio -bs=4k -size=1G -numjobs=1 -runtime=1000 -group_reporting -filename=iotest -name=Rand_Read_Testing
    • 写吞吐量
      fio -direct=1 -iodepth=64 -rw=write -ioengine=libaio -bs=64k -size=1G -numjobs=1 -runtime=1000 -group_reporting -filename=iotest -name=Write_PPS_Testing
    • 读吞吐量
      fio -direct=1 -iodepth=64 -rw=read -ioengine=libaio -bs=64k -size=1G -numjobs=1 -runtime=1000 -group_reporting -filename=iotest -name=Read_PPS_Testing
  • 四台ECS实例参与压测时(取iodepth=64):
    • 随机写IOPS
      fio -direct=1 -iodepth=96 -rw=randwrite -ioengine=libaio -bs=4k -size=1G -numjobs=1 -runtime=1000 -group_reporting -filename=iotest -name=Rand_Write_Testing
    • 随机读IOPS
      fio -direct=1 -iodepth=96 -rw=randread -ioengine=libaio -bs=4k -size=1G -numjobs=1 -runtime=1000 -group_reporting -filename=iotest -name=Rand_Read_Testing
    • 写吞吐量
      fio -direct=1 -iodepth=64 -rw=write -ioengine=libaio -bs=64k -size=1G -numjobs=1 -runtime=1000 -group_reporting -filename=iotest -name=Write_PPS_Testing
    • 读吞吐量
      fio -direct=1 -iodepth=64 -rw=read -ioengine=libaio -bs=64k -size=1G -numjobs=1 -runtime=1000 -group_reporting -filename=iotest -name=Read_PPS_Testing

FIO参数取值说明

下表以测试云盘随机写IOPS(randwrite)的命令为例,说明各种参数的含义。
参数 说明
-direct=1 表示测试时忽略I/O缓存,数据直写。
-iodepth=128 表示使用异步I/O(AIO)时,同时发出I/O数的上限为128。
-rw=randwrite 表示测试时的读写策略为随机写(random writes)。其它测试可以设置为:
  • randread(随机读random reads)
  • read(顺序读sequential reads)
  • write(顺序写sequential writes)
  • randrw(混合随机读写mixed random reads and writes)
-ioengine=libaio 表示测试方式为libaio(Linux AIO,异步I/O)。应用程序使用I/O通常有两种方式:
  • 同步

    同步的I/O一次只能发出一个I/O请求,等待内核完成才返回。这样对于单个线程iodepth总是小于1,但是可以透过多个线程并发执行来解决。通常会用16−32根线程同时工作将iodepth塞满。

  • 异步

    异步的I/O通常使用libaio这样的方式一次提交一批I/O请求,然后等待一批的完成,减少交互的次数,会更有效率。

-bs=4k 表示单次I/O的块文件大小为4KiB。默认值也是4KiB。
  • 测试IOPS时,建议将bs设置为一个较小的值,如4k。
  • 测试吞吐量时,建议将bs设置为一个较大的值,如1024k。
-size=1G 表示测试文件大小为1GiB。
-numjobs=1 表示测试线程数为1。
-runtime=1000 表示测试时间为1000秒。如果未配置,则持续将前述-size指定大小的文件,以每次-bs值为分块大小写完。
-group_reporting 表示测试结果里汇总每个进程的统计信息,而非以不同job汇总展示信息。
-filename=iotest 指定测试文件的名称,例如iotest
-name=Rand_Write_Testing 表示测试任务名称为Rand_Write_Testing,可以随意设定。