衡量指标
一般使用以下指标衡量云硬盘的性能:
- IOPS:每秒读/写次数,单位为次(计数)。存储设备的底层驱动类型决定了不同的 IOPS。
- 吞吐量:每秒的读写数据量,单位为MB/s。
- 时延:I/O 操作的发送时间到接收确认所经过的时间,单位为秒。
测试工具
FIO 是测试磁盘性能的工具,用来对硬件进行压力测试和验证,本文以 FIO 为例。
使用 FIO 时,建议配合使用 libaio 的 I/O 引擎进行测试。请参考 工具安装 完成 FIO 和 libaio 的安装。
- 请不要在系统盘上进行 FIO 测试,避免损坏系统重要文件。
- 为避免底层文件系统元数据损坏导致数据损坏,请不要在业务数据盘上进行测试。
- 请确保/etc/fstab文件配置项中没有被测硬盘的挂载配置,否则将导致云服务器启动失败。
测试对象建议
- 建议在空闲的、未保存重要数据的硬盘上进行 FIO 测试,并在测试完后重新制作被测硬盘的文件系统。
- 测试硬盘性能时,建议直接测试裸数据盘(如 /dev/vdb)。
- 测试文件系统性能时,推荐指定具体文件测试(如 /data/file)。
工具安装
- 本文以 CentOS 7.6 操作系统的云服务器为例。
- 执行以下命令,查看云硬盘是否4KiB对齐。
fdisk -lu
如下图所示,若返回结果中的 Start 值能被8整除即是4KiB对齐。否则请完成4KiB对齐后再进行测试。
3. 依次执行以下命令,安装测试工具 FIO 和 libaio。
yum install libaio libaio-devel fio -y
安装完成后,请参考测试示例开始云硬盘性能测试。
测试示例
不同场景的测试公式基本一致,只有 rw、iodepth 和 bs(block size)三个参数的区别。例如,每个工作负载适合最佳 iodepth 不同,取决于您的特定应用程序对于 IOPS 和延迟的敏感程度。
参数说明:
参数名 | 说明 | 取值样例 |
bs | 每次请求的块大小。取值包括4k、8k及16k等。 | 4k |
ioengine | I/O 引擎。推荐使用 Linux 的异步 I/O 引擎。 | libaio |
iodepth | 请求的 I/O 队列深度。 | 1 |
direct | 指定 direct 模式。
默认为 True(1)。 | 1 |
rw | 读写模式。取值包括顺序读(read)、顺序写(write)、随机读(randread)、随机写(randwrite)、混合随机读写(randrw)和混合顺序读写(rw,readwrite)。 | read |
time_based | 指定采用时间模式。无需设置该参数值,只要 FIO 基于时间来运行。 | N/A |
runtime | 指定测试时长,即 FIO 运行时长。 | 600 |
refill_buffers | FIO 将在每次提交时重新填充 I/O 缓冲区。默认设置是仅在初始时填充并重用该数据。 | N/A |
randrepeat | 随机序列是否可重复,True(1)表示随机序列可重复,False(0)表示随机序列不可重复。默认为 True(1)。 | 0 |
name | job 的名称。 | fio-read |
filename | 测试对象,即待测试的磁盘设备名称。 | /dev/sdb |
查看block设备信息,选择需要测试的设备,一般选择非系统盘/dev/vdb
lsblk -p
常见用例如下:
- bs = 4k iodepth = 1:随机读/写测试,能反映硬盘的时延性能
执行以下命令,测试硬盘的随机读时延。
fio -bs=4k -ioengine=libaio -iodepth=1 -direct=1 -rw=randread -time_based -runtime=600 -refill_buffers -norandommap -randrepeat=0 -group_reporting -name=fio-randread-lat --size=10G -filename=/dev/vdb
执行以下命令,测试硬盘的随机写时延。
fio -bs=4k -ioengine=libaio -iodepth=1 -direct=1 -rw=randwrite -time_based -runtime=600 -refill_buffers -norandommap -randrepeat=0 -group_reporting -name=fio-randwrite-lat --size=10G -filename=/dev/vdb
执行以下命令,测试硬盘的随机混合读写时延性能。
fio --bs=4k --ioengine=libaio --iodepth=1 --direct=1 --rw=randrw --time_based --runtime=100 --refill_buffers --norandommap --randrepeat=0 --group_reporting --name=fio-read --size=1G --filename=/dev/vdb
测试结果如下图所示:usec微妙(1秒=1000,000微秒)
[root@prod unicloud]# fio --bs=4k --ioengine=libaio --iodepth=1 --direct=1 --rw=randrw --time_based --runtime=100 --refill_buffers --norandommap --randrepeat=0 --group_reporting --name=fio-read --size=1G --filename=/dev/vdb
fio-read: (g=0): rw=randrw, bs=(R) 4096B-4096B, (W) 4096B-4096B, (T) 4096B-4096B, ioengine=libaio, iodepth=1
fio-3.7
Starting 1 process
Jobs: 1 (f=1): [m(1)][100.0%][r=1440KiB/s,w=1460KiB/s][r=360,w=365 IOPS][eta 00m:00s]
fio-read: (groupid=0, jobs=1): err= 0: pid=14984: Wed Aug 11 13:26:24 2021
read: IOPS=169, BW=676KiB/s (693kB/s)(66.1MiB/100001msec)
slat (usec): min=5, max=104, avg=13.07, stdev= 8.29
clat (usec): min=4, max=12607, avg=675.36, stdev=397.73
lat (usec): min=29, max=12632, avg=689.44, stdev=398.39
clat percentiles (usec):
| 1.00th=[ 29], 5.00th=[ 34], 10.00th=[ 37], 20.00th=[ 48],
| 30.00th=[ 619], 40.00th=[ 734], 50.00th=[ 807], 60.00th=[ 865],
| 70.00th=[ 914], 80.00th=[ 979], 90.00th=[ 1057], 95.00th=[ 1156],
| 99.00th=[ 1270], 99.50th=[ 1319], 99.90th=[ 1483], 99.95th=[ 1582],
| 99.99th=[ 4113]
bw ( KiB/s): min= 184, max= 1568, per=99.41%, avg=672.01, stdev=359.17, samples=199
iops : min= 46, max= 392, avg=167.98, stdev=89.80, samples=199
write: IOPS=167, BW=669KiB/s (685kB/s)(65.3MiB/100001msec)
slat (usec): min=5, max=118, avg=13.69, stdev= 8.69
clat (usec): min=955, max=130008, avg=5257.35, stdev=6203.62
lat (usec): min=963, max=130017, avg=5272.06, stdev=6203.96
clat percentiles (usec):
| 1.00th=[ 1303], 5.00th=[ 1467], 10.00th=[ 1565], 20.00th=[ 1680],
| 30.00th=[ 1778], 40.00th=[ 1860], 50.00th=[ 1942], 60.00th=[ 2040],
| 70.00th=[ 2212], 80.00th=[14615], 90.00th=[15664], 95.00th=[16319],
| 99.00th=[18220], 99.50th=[23725], 99.90th=[34866], 99.95th=[39584],
| 99.99th=[61080]
bw ( KiB/s): min= 248, max= 1432, per=99.43%, avg=664.16, stdev=351.29, samples=199
iops : min= 62, max= 358, avg=166.02, stdev=87.82, samples=199
lat (usec) : 10=0.01%, 20=0.01%, 50=10.26%, 100=1.13%, 250=0.67%
lat (usec) : 500=0.21%, 750=8.96%, 1000=20.72%
lat (msec) : 2=36.23%, 4=9.53%, 10=0.18%, 20=11.68%, 50=0.38%
lat (msec) : 100=0.01%, 250=0.01%
cpu : usr=0.30%, sys=0.73%, ctx=33633, majf=0, minf=34
IO depths : 1=100.0%, 2=0.0%, 4=0.0%, 8=0.0%, 16=0.0%, 32=0.0%, >=64=0.0%
submit : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
complete : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
issued rwts: total=16910,16724,0,0 short=0,0,0,0 dropped=0,0,0,0
latency : target=0, window=0, percentile=100.00%, depth=1
Run status group 0 (all jobs):
READ: bw=676KiB/s (693kB/s), 676KiB/s-676KiB/s (693kB/s-693kB/s), io=66.1MiB (69.3MB), run=100001-100001msec
WRITE: bw=669KiB/s (685kB/s), 669KiB/s-669KiB/s (685kB/s-685kB/s), io=65.3MiB (68.5MB), run=100001-100001msec
Disk stats (read/write):
vdb: ios=16883/16674, merge=0/0, ticks=11365/87747, in_queue=99110, util=99.19%
slat=提交延迟
clat=完成延迟
lat=响应时间
- bs = 128k iodepth = 32:顺序读/写测试,能反映硬盘的吞吐性能
执行以下命令,测试硬盘的顺序读吞吐带宽。
fio -bs=128k -ioengine=libaio -iodepth=32 -direct=1 -rw=read -time_based -runtime=600 -refill_buffers -norandommap -randrepeat=0 -group_reporting -name=fio-read-throughput --size=10G -filename=/dev/vdb
执行以下命令,测试硬盘的顺序写吞吐带宽。
fio -bs=128k -ioengine=libaio -iodepth=32 -direct=1 -rw=write -time_based -runtime=600 -refill_buffers -norandommap -randrepeat=0 -group_reporting -name=fio-write-throughput --size=10G -filename=/dev/vdb
执行以下命令,测试 SSD 云硬盘的顺序读吞吐性能。
fio --bs=128k --ioengine=libaio --iodepth=32 --direct=1 --rw=read --time_based --runtime=100 --refill_buffers --norandommap --randrepeat=0 --group_reporting --name=fio-rw --size=1G --filename=/dev/vdb
测试结果如下图所示:
# fio --bs=128k --ioengine=libaio --iodepth=32 --direct=1 --rw=read --time_based --runtime=100 --refill_buffers --norandommap --randrepeat=0 --group_reporting --name=fio-rw --size=1G --filename=/dev/vdb
fio-rw: (g=0): rw=read, bs=(R) 128KiB-128KiB, (W) 128KiB-128KiB, (T) 128KiB-128KiB, ioengine=libaio, iodepth=32
fio-3.7
Starting 1 process
Jobs: 1 (f=1): [R(1)][100.0%][r=256MiB/s,w=0KiB/s][r=2049,w=0 IOPS][eta 00m:00s]
fio-rw: (groupid=0, jobs=1): err= 0: pid=15216: Wed Aug 11 13:30:26 2021
read: IOPS=2050, BW=256MiB/s (269MB/s)(25.0GiB/100015msec)
slat (usec): min=6, max=532, avg=18.81, stdev=12.74
clat (usec): min=40, max=30460, avg=15585.56, stdev=823.53
lat (usec): min=52, max=30509, avg=15605.39, stdev=822.54
clat percentiles (usec):
| 1.00th=[13698], 5.00th=[14484], 10.00th=[14746], 20.00th=[15008],
| 30.00th=[15270], 40.00th=[15401], 50.00th=[15533], 60.00th=[15795],
| 70.00th=[15926], 80.00th=[16188], 90.00th=[16450], 95.00th=[16712],
| 99.00th=[17433], 99.50th=[17695], 99.90th=[18220], 99.95th=[18744],
| 99.99th=[20055]
bw ( KiB/s): min=261120, max=313856, per=100.00%, avg=262399.94, stdev=3678.42, samples=200
iops : min= 2040, max= 2452, avg=2050.00, stdev=28.74, samples=200
lat (usec) : 50=0.01%, 100=0.01%
lat (msec) : 4=0.03%, 10=0.13%, 20=99.83%, 50=0.01%
cpu : usr=1.11%, sys=5.46%, ctx=187261, majf=0, minf=547
IO depths : 1=0.1%, 2=0.1%, 4=0.1%, 8=0.1%, 16=0.1%, 32=100.0%, >=64=0.0%
submit : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.0%, 64=0.0%, >=64=0.0%
complete : 0=0.0%, 4=100.0%, 8=0.0%, 16=0.0%, 32=0.1%, 64=0.0%, >=64=0.0%
issued rwts: total=205034,0,0,0 short=0,0,0,0 dropped=0,0,0,0
latency : target=0, window=0, percentile=100.00%, depth=32
Run status group 0 (all jobs):
READ: bw=256MiB/s (269MB/s), 256MiB/s-256MiB/s (269MB/s-269MB/s), io=25.0GiB (26.9GB), run=100015-100015msec
Disk stats (read/write):
vdb: ios=204793/0, merge=0/0, ticks=3190576/0, in_queue=3190805, util=99.97%
bw=平均IO带宽
- bs = 4k iodepth = 32:随机读/写测试,能反映硬盘的 IOPS 性能
执行以下命令,测试硬盘的随机读 IOPS。
fio -bs=4k -ioengine=libaio -iodepth=32 -direct=1 -rw=randread -time_based -runtime=600 -refill_buffers -norandommap -randrepeat=0 -group_reporting -name=fio-randread-iops --size=10G -filename=/dev/vdb
执行以下命令,测试硬盘的随机写 IOPS。
fio -bs=4k -ioengine=libaio -iodepth=32 -direct=1 -rw=randwrite -time_based -runtime=600 -refill_buffers -norandommap -randrepeat=0 -group_reporting -name=fio-randwrite-iops --size=10G -filename=/dev/vdb
测试 SSD 云硬盘的随机读 IOPS 性能。如下图所示:
执行以下命令,线程50(-numjobs=50),在混合读写的模式下写占70%(-rwmixread=70 ), 测试硬盘的随机读写 IOPS。
fio -bs=4k -ioengine=libaio -iodepth=32 -direct=1 -rw=randrw -rwmixread=70 -ioengine=psync -bs=4k -size=10G -numjobs=50 -runtime=180 -group_reporting -name=randrw_70read_4k_local -filename=/dev/vdb
IOPS (Input/Output Per Second)即每秒的输入输出量(或读写次数),是衡量磁盘性能的主要指标之一。IOPS是指单位时间内系统能处理的I/O请求数量,一般以每秒处理的I/O请求数量为单位,I/O请求通常为读或写数据操作请求。