环境准备工作
磁盘填充测试数据
Q:为什么要进行数据填充?
A:针对空块与含数据的块,当从两者中读取数据读时,将会得到不同的性能结果。所以为使结果更加准确,我们将对块设备进行数据填充;
fio --name=fill_disk \ --filename=/dev/sdc --filesize=29313144Ki \ --ioengine=libaio --direct=1 --verify=0 --randrepeat=0 \ --bs=128K --iodepth=64 --rw=randwrite # 该命令参数将完成数据填充的任务。鉴于其参数并不符合性能测试要求,所以我们不无需关注其输出的报告;
存储测试配置信息
命令选项如下,其为各个测试场景中的通用选项:
–filename=/dev/sdc:物理磁盘路径:/dev/sdc
–filesize=29313144Ki:我们的磁盘大小,30016659456 / 1024 = 29313144Ki (~28G)
–time_based:基于时间来进行基准测试,即任务仅云新特定时间;
–runtime=1m:测试任务仅运行一分钟,得到测试结果即可,无需长时间运行;
–ramp_time=2s:当使得性能趋于稳定后,再输出性能测试结果(在 2s 后);
–ioengine=libaio:使用异步 IO 引擎,以模拟更多负载;
–direct=1:使用 non-buffered I/O,将数据直接写入物理磁盘。
–verify=0:无需要对写入的数据进行验证
–randrepeat=0:随机产生数据;
Bandwidth(带宽)
–bs=1M:块大小对带宽的测试结果是有影响的,具体块大小取决于业务场景;
–iodepth=64:需要足够的 I/O depth,以产生足够多个 IO 负载,我们这里 I/O depth 为 64;
–rw=write:需要通过 Seq. r/w 来实现带宽测试,而 Rnd. r/w 将消耗更多时间进行寻道,进而无法得到准确的结果;
–numjobs=16:需要创建多个进程,以产生足够多的 IO 负载,我们这里创建 16 个进程;
–offset_increment=1832071Ki:将文件分为 16 部分(29313144÷16),使得每个进程仅写入自己所属的部分;
–group_reporting,能够将多个进程的输出结果进行聚合显示,而非显示每个进程的测试报告;
写入带宽(Seq. Bandwidth)
fio --name=write_bandwidth_test \ --filename=/dev/sdc --filesize=29313144Ki \ --time_based --ramp_time=2s --runtime=1m \ --ioengine=libaio --direct=1 --verify=0 --randrepeat=0 \ --bs=1M --iodepth=64 --rw=write --numjobs=16 --offset_increment=1832071Ki --group_reporting
通过创建线程来执行测试:
# --numjobs=4 --thread fio --name=read_bandwidth_test \ --filename=/dev/sdc --filesize=29313144Ki \ --time_based --ramp_time=2s --runtime=1m \ --ioengine=libaio --direct=1 --verify=0 --randrepeat=0 \ --bs=1M --iodepth=64 --rw=write --numjobs=4 --thread --offset_increment=1832071Ki ...
读取带宽(Rnd. Bandwidth)
fio --name=read_bandwidth_test \ --filename=/dev/sdc --filesize=29313144Ki \ --time_based --ramp_time=2s --runtime=1m \ --ioengine=libaio --direct=1 --verify=0 --randrepeat=0 \ --bs=1M --iodepth=64 --rw=read --numjobs=16 --offset_increment=1832071Ki --group_reporting
通过创建线程来执行测试:
# --numjobs=4 --thread fio --name=read_bandwidth_test \ --filename=/dev/sdc --filesize=29313144Ki \ --time_based --ramp_time=2s --runtime=1m \ --ioengine=libaio --direct=1 --verify=0 --randrepeat=0 \ --bs=1M --iodepth=64 --rw=read --numjobs=4 --thread --offset_increment=1832071Ki ...
IOPS(每秒 IO 数)
–rw=randwrite:写入 IOPS 需要使用 Rnd. Write 实现;读取 IOPS 需要使用 Rnd. Read 实现;
–iodepth=256:要实现最大 IOPS,必须维护一个深 I/O 队列。例如,如果写入延迟为 1ms,则 VM 最多可为每个运行中的 I/O 实现 1k IOPS。要达到 1.5w Write IOPS,VM 必须保持至少 15 个 I/O 处于运行状态。如果磁盘和虚拟机能够达到 3w Write IOPS,则运行中的 I/O 数量必须至少为 30 I/O
–bs=4K:采用 4K 块大小是基于一些默认规则:底层存储的块大小为 4K,其亦以 4K 作为读写单位,并且我们要测试的是存储单个块(页)的 IOPS 速度,此外厂商的给出的 IOPS 指标也是基于 4K 块。如果 I/O blocksize > 4 KB,那么在达到存储 IOPS 限制之前会先达到 bandwidth 限制,导致测试结果不准确。严谨地讲,具体 blocksize 取决于对业务数据的采集分析,我们这里仅是通用测试;
写入次数(Rnd. IOPS)
fio --name=write_iops_test \ --filename=/dev/sdc --filesize=29313144Ki \ --time_based --ramp_time=2s --runtime=1m \ --ioengine=libaio --direct=1 --verify=0 --randrepeat=0 \ --bs=4K --iodepth=256 --rw=randwrite
读取次数(Rnd. IOPS)
fio --name=read_iops_test \ --filename=/dev/sdc --filesize=29313144Ki \ --time_based --ramp_time=2s --runtime=1m \ --ioengine=libaio --direct=1 --verify=0 --randrepeat=0 \ --bs=4K --iodepth=256 --rw=randread
Latency(延迟)
–rw=randwrite:通过 Rnd. Write 测试写入延迟;通过 Rnd. Read 测试读取延迟;
–iodepth=4:在测试 I/O 延迟时,不得达到最大 bandwidth 或 IOPS 限制,否则观察到的延迟不会反映实际的 I/O 延迟。例如,假设在 I/O depth = 30 时,将达到 IOPS 限制。如果将 I/O depth 增加一倍,此时由于总 IOPS 保持不变,将导致报告的 I/O 延迟加倍;
–bs=4K:依旧使用 4K 块大小,测试 4K 块的 IO 延迟;
写入延迟(Rnd. Latency)
fio --name=write_latency_test \ --filename=/dev/sdc --filesize=29313144Ki \ --time_based --ramp_time=2s --runtime=1m \ --ioengine=libaio --direct=1 --verify=0 --randrepeat=0 \ --bs=4K --iodepth=4 --rw=randwrite
读取延迟(Rnd. Latency)
fio --name=read_latency_test \ --filename=/dev/sdc --filesize=29313144Ki \ --time_based --ramp_time=2s --runtime=1m \ --ioengine=libaio --direct=1 --verify=0 --randrepeat=0 \ --bs=4K --iodepth=4 --rw=randread
存储性能测试总结
Q:针对如上测试结果,该硬盘的性能指标是好还是坏?
A:我们无法单纯的去讨论结果的好坏,需要(1)将其与厂商给到的基准测试结果进行对比,了解差距;(2)要与业务需求进行对比,以了解该磁盘能否满足业务需求;
参考文献
Compute Engine Documentation/Benchmarking persistent disk performance
Benchmarking persistent disk performance
Alibaba Cloud Community/How to Use FIO to Test the IO Performance of ECS Local SSD and ESSD (Part 1)