存储性能测试常用工具记录
记录块存储、文件存储、对象存储等存储类型常用的性能测试工具及对应的测试命令。
存储类型 | 测试工具 | 备注 |
---|---|---|
块存储 | fio,rbd bench | 指标:iops、吞吐量 |
文件存储 | fio,rados bench | 指标:iops、吞吐量 |
块存储 | cosbench | 指标:吞吐量 |
1. 块存储性能测试
1.1 fio性能测试
FIO是一款开源的 I/O 压力测试工具,主要是用来测试磁盘的IO性能。它可以支持多种不同的I/O引擎。
1.1.1 FIO安装
# centos yum安装
# yum install fio
# yum install libaio-devel # 使用libaio发起异步IO请求。
# ubuntu apt安装
$ sudo apt-get install libaio-dev
# 源码编译安装
# wget http://brick.kernel.dk/snaps/fio-2.0.7.tar.gz
# yum install libaio-devel
# tar -zxvf fio-2.0.7.tar.gz
# cd fio-2.0.7
# ./configure
# make && make install
1.1.2 fio参数解读
# 运行参数
fio -filename=/dev/sdb1 -direct=1 -iodepth 1 -thread -rw=randread -ioengine=psync -bs=4k -size=50G -numjobs=10 -runtime=1000 -group_reporting -name=mytest
说明:
- filename=/dev/sdb1
定义测试文件(设备)的名称。此处选择文件,则代表测试文件系统的性能,例如:-filename=/opt/fiotest/fiotest.txt;此处选择设备名称,则代表测试裸盘的性能,例:-filename=/dev/vdb1 。
注:如果在已经分区、并创建文件系统,且已写入数据的磁盘上进行性能测试,请注意 filename选择指定文件,以避免覆盖文件系统和原有数据。
-
direct=1
定义是否使用direct IO,可选值如下:值为0,表示使用buffered IO;值为1,表示使用 direct IO。取值1,测试过程绕过机器自带的buffer,使测试结果更真实。 -
iodepth 1
队列深度,只有使用libaio时才有意义,这是一个可以影响IOPS的参数,通常情况下为1。定义测试时的IO队列深度,默认为1。此处定义的队列深度是指每个线程的队列深度,如果有多个线程测试,意味着每个线程都是此处定义的队列深度。fio总的IO并发数 =iodepth * numjobs。 -
rw=randwrite
定义测试时的读写策略,可选read,write,randread,randwrite,randrw,readwrite: -
ioengine=psync
io引擎使用pync方式,如果要使用libaio引擎,需要yum install libaio-devel包。定义fio如何下发IO请求,通常有同步IO和异步IO:同步IO一次只能发出一个IO请求, 等待内核完成后才返回。这样对于单个线程IO队列深度总是小于1,但是可以透过多个线程并发执行来解决。通常会用16~32个线程同时工作把IO队列深度塞满。异步IO则通常使用libaio这样的方式一次提交一批IO请求,然后等待一批的完成,减少交互的次 数,会更有效率。 -
bs=4k
定义IO的块大小(block size),单位是k、K、m和M等,默认IO块大小为4 KB。 -
bsrange=512-2048
同上,提定数据块的大小范围 -
size=50G
定义测试IO操作的数据量,若未指定runtime这类参数,fio会将指定大小的数据量全部读/写完成,然后才停止测试。该参数的值,可以是带单位的数字,比如size=10G,表示读/写的数据量为10GB;也可是百分数,比如size=20%,表示读/写的数据量占该设 备总文件的20%的空间。建议测试数据量为内存两倍大,尽量避免缓存影响。 -
numjobs=10
定义测试的并发线程数。 -
runtime=1000
定义测试时间。如果未配置,则持续将size指定的文件大小,以每次bs值为分块大小读/ 写完。 -
rwmixwrite=30
在混合读写的模式下,写占30% -
group_reporting
定义测试结果显示模式,group_reporting 表示汇总每个进程的统计信息,而非以不同 job汇总展示信息。
name=mytest:定义测试任务名称。
其他参数:
- lockmem=1g
只使用1g内存进行测试。 - zero_buffers
用0初始化系统buffer。 - nrfiles=8
每个进程生成文件的数量。 - time_based
如果设置的话,即使file已被完全读写或写完,也要执行完runtime规定的时间。它是通过循环执行相同的负载来实现的,与runtime相对应。 - ramp_time=time
设定在记录任何性能信息之前要运行特定负载的时间。这个用来等性能稳定后,再记录日志
1.1.3 测试场景
4k随机写iops
fio -filename=/tmp/fio.img -direct=1 -iodepth 32 -thread -rw=randwrite -ioengine=libaio -bs=4k -size=200m -numjobs=8 -runtime=60 -group_reporting -name=mytest
4k随机读iops
fio -filename=/tmp/fio.img -direct=1 -iodepth 32 -thread -rw=randread -ioengine=libaio -bs=4k -size=200m -numjobs=8 -runtime=60 -group_reporting -name=mytest
4k随机混合读写iops
fio -filename=/tmp/fio.img -direct=1 -iodepth 32 -thread -rw=randrw -rwmixread=70 -ioengine=libaio -bs=4k -size=200m -numjobs=8 -runtime=60 -group_reporting -name=mytest
1M顺序写吞吐量
fio -filename=/tmp/fio.img -direct=1 -iodepth 32 -thread -rw=write -ioengine=libaio -bs=1M -size=200m -numjobs=8 -runtime=60 -group_reporting -name=mytest
1.1.4 fio测试结果解读
[root@i-byNYDrAOM ~]# fio -filename=/tmp/fio.img -direct=1 -iodepth 32 -thread -rw=randrw -rwmixread=70 -ioengine=libaio -bs=4k -size=200m -numjobs=8 -runtime=60 -group_reporting -name=mytest
mytest: (g=0): rw=randrw, bs=(R) 4096B-4096B, (W) 4096B-4096B, (T) 4096B-4096B, ioengine=libaio, iodepth=32
...
fio-3.7
Starting 8 threads
Jobs: 8 (f=8): [m(8)][100.0%][r=3083KiB/s,w=1405KiB/s][r=770,w=351 IOPS][eta 00m:00s]
mytest: (groupid=0, jobs=8): err= 0: pid=81241: Tue Mar 12 17:19:53 2024
read: IOPS=782, BW=3129KiB/s (3204kB/s)(184MiB/60230msec)
slat (nsec): min=1643, max=40209k, avg=132078.80, stdev=1381884.87
clat (msec): min=3, max=505, avg=228.62, stdev=15.45
lat (msec): min=3, max=505, avg=228.76, stdev=15.51
clat percentiles (msec):
| 1.00th=[ 222], 5.00th=[ 224], 10.00th=[ 226], 20.00th=[ 226],
| 30.00th=[ 228], 40.00th=[ 228], 50.00th=[ 228], 60.00th=[ 228],
| 70.00th=[ 230], 80.00th=[ 232], 90.00th=[ 234], 95.00th=[ 236],
| 99.00th=[ 247], 99.50th=[ 259], 99.90th=[ 384], 99.95th=[ 422],
| 99.99th=[ 447]
bw ( KiB/s): min= 280, max= 568, per=12.50%, avg=391.10, stdev=34.73, samples=960
iops : min= 70, max= 142, avg=97.74, stdev= 8.68, samples=960
write: IOPS=339, BW=1358KiB/s (1391kB/s)(79.9MiB/60230msec)
slat (nsec): min=1786, max=80626k, avg=136407.47, stdev=1474072.30
clat (usec): min=1092, max=456627, avg=226632.82, stdev=16728.19
lat (usec): min=1094, max=456633, avg=226769.52, stdev=16794.41
clat percentiles (msec):
| 1.00th=[ 222], 5.00th=[ 224], 10.00th=[ 226], 20.00th=[ 226],
| 30.00th=[ 226], 40.00th=[ 228], 50.00th=[ 228], 60.00th=[ 228],
| 70.00th=[ 228], 80.00th=[ 228], 90.00th=[ 230], 95.00th=[ 230],
| 99.00th=[ 236], 99.50th=[ 245], 99.90th=[ 393], 99.95th=[ 426],
| 99.99th=[ 447]
bw ( KiB/s): min= 72, max= 288, per=12.51%, avg=169.71, stdev=31.15, samples=960
iops : min= 18, max= 72, avg=42.39, stdev= 7.79, samples=960
lat (msec) : 2=0.04%, 4=0.01%, 10=0.04%, 20=0.10%, 50=0.14%
lat (msec) : 100=0.08%, 250=98.97%, 500=0.63%, 750=0.01%
cpu : usr=0.03%, sys=0.12%, ctx=66346, majf=0, minf=13
IO depths : 1=0.1%, 2=0.1%, 4=0.1%, 8=0.1%, 16=0.2%, 32=99.6%, >=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=47117,20448,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=3129KiB/s (3204kB/s), 3129KiB/s-3129KiB/s (3204kB/s-3204kB/s), io=184MiB (193MB), run=60230-60230msec
WRITE: bw=1358KiB/s (1391kB/s), 1358KiB/s-1358KiB/s (1391kB/s-1391kB/s), io=79.9MiB (83.8MB), run=60230-60230msec
Disk stats (read/write):
vda: ios=47069/20446, merge=0/2, ticks=10738703/4625467, in_queue=15364170, util=99.88%
-
IOPS: 每秒的输入输出量(或读写次数),是衡量磁盘性能的主要指标之一;
-
Bw: 带宽;
-
I/O延迟:包括三种:slat,clat,lat;关系是 lat = slat + clat;
- slat 表示fio submit某个I/O的延迟;
- clat 表示fio complete某个I/O的延迟;
- lat 表示从fio将请求提交给内核,再到内核完成这个I/O为止所需要的时间;
1.1.5 fio配置文件
执行多个测试的时候,由于命令行参数过多影响,不太直观,可以将参数写到配置文件中。把全局变量和测试变化的参数写在不同的块里,最后加配置文件运行即可。例如,上述4个场景可以写一个配置文件fio-test.cfg,内容如下:
[global]
ioengine=libaio
size=200m
direct=1
thread
filename=/tmp/fio.img
numjobs=8
iodepth=32
runtime=60
group_reporting
[4k-randwrite]
bs=4k
rw=randwrite
stonewall
[4k-randread]
bs=4k
rw=randread
stonewall
[4k-randrw]
bs=4k
rw=randrw
rwmixread=70
stonewall
[1m-write]
bs=1M
rw=write
stonewall
执行fio test-fio.cfg运行测试。
1.2 rbd bench 性能测试
不同于fio、vdbench等上层应用接口测试工具,ceph提供了一些自带的基准性能测试工具,用于测试rados、rbd等底层存储基准性能,可以比对底层基准性能和上层应用基准性能,确定潜在可调优的空间。
- 提前在存储侧创建测试的镜像test.img
- 根据环境情况测试命令是否带配置文件和密钥。
部分查询命令:
# 查询rbd存储池:
ceph df -c xxx.conf
1.2.1 测试参数
rbd bench <rbd-name> --io-type <io-type> --io-size <io-size> --io-pattern <io-pattern> --io-threads <io-threads> --io-total <total-size>
- rbd-name:指定测试块设备名称,如rbd/rbd01
- –io-type:指定测试IO类型,可选参数write、read
- –io-size:指定测试IO块大小,单位为byte,默认参数为4096(4KB)
- –io-pattern:指定测试IO模式,可选参数为seq(顺序)、rand(随机)
- –io-threads:指定测试IO线程数,默认参数为16
- –io-total:指定测试总写入数据量,单位为byte,默认参数为1073741824(1G)
1.2.2 测试场景1
测试 4K 随机写
rbd bench --io-size 4K --io-threads 16 --io-pattern rand --io-type write .diskpool01.rbd/test.img
测试 4K 随机读
rbd bench --io-size 4K --io-threads 16 --io-pattern rand --io-type read .diskpool01.rbd/test.img
测试 4K 随机混合读写
rbd bench --io-size 4K --io-threads 16 --io-pattern rand --io-type readwrite --rw-mix-read 70 .diskpool01.rbd/test.img
测试 1M 顺序写
rbd bench --io-size 1M --io-threads 16 --io-pattern rand --io-type write .diskpool01.rbd/test.img
1.2.3 测试场景2
大文件吞吐量测试
# 1M顺序写, 指定线程数为32,写入数据量为100G
rbd bench .diskpool01.rbd/test.img --io-type write --io-size 1M --io-pattern seq --io-threads 32 --io-total 100G
# 1M顺序读,指定线程数为32,写入数据量为100G
rbd bench .diskpool01.rbd/test.img --io-type read --io-size 1M --io-pattern seq --io-threads 32 --io-total 100G
小文件IOPS测试
# 4K随机写,指定线程数为32,写入数据量为10G。
rbd bench .diskpool01.rbd/test.img --io-type write --io-size 4K --io-pattern rand --io-threads 32 --io-total 10G
# 4K随机读,指定线程数为32,写入数据量为10G
rbd bench .diskpool01.rbd/test.img --io-type read --io-size 4K --io-pattern rand --io-threads 32 --io-total 10G
结果分析
[root@xxx]# rbd bench .diskpool01.rbd/test.img --io-type write --io-size 1M --io-pattern seq --io-threads 32 --io-total 10G -c 40e2f909-df4d-43fa-8869-72abc3369175.conf -k 40e2f909-df4d-43fa-8869-72abc3369175.keyring
bench type write io_size 1048576 io_threads 32 bytes 10737418240 pattern sequential
SEC OPS OPS/SEC BYTES/SEC
1 1113 1145.11 1200735490.64
2 2245 1138.27 1193557759.28
3 3376 1135.84 1191017610.72
4 4507 1134.63 1189748278.96
5 5639 1134.03 1189121858.19
6 6742 1125.72 1180403631.48
7 7873 1125.56 1180236727.92
8 9006 1126.01 1180711692.42
9 10138 1125.91 1180606676.60
elapsed: 9 ops: 10240 ops/sec: 1126.43 bytes/sec: 1181145837.54
测试结果取最后一行elapsed的值,带宽为bytes/sec对应参数值(单位为bytes/sec,可根据需要转换为MB/s),IOPS为ops/sec对应参数值
测试参数带-c和-k指定ceph配置文件和密钥文件
2. 文件存储性能测试
2.1 fio 性能测试
文件存储挂载到/mnt目录:
2.2 测试场景
4k随机读iops
fio -numjobs=1 -iodepth=128 -direct=1 -ioengine=libaio -sync=1 -rw=randread -bs=4K -size=1G -time_based -runtime=60 -name=Fio -directory=/mnt
4k随机写iops
fio -numjobs=1 -iodepth=128 -direct=1 -ioengine=libaio -sync=1 -rw=randwrite -bs=4K -size=1G -time_based -runtime=60 -name=Fio -directory=/mnt
1M随机读吞吐量
fio -numjobs=1 -iodepth=128 -direct=1 -ioengine=libaio -sync=1 -rw=randread -bs=1M -size=1G -time_based -runtime=60 -name=Fio -directory=/mnt
2.1.4 1M随机写吞吐量
fio -numjobs=1 -iodepth=128 -direct=1 -ioengine=libaio -sync=1 -rw=randwrite -bs=1M -size=1G -time_based -runtime=60 -name=Fio -directory=/mnt
2.2 rados bench测试
rados bench为ceph自带的基准测试工具,rados bench用于测试rados存储池底层性能,该工具可以测试写、顺序读、随机读三种类型.
2.2.1 测试参数
# 测试参数
rados bench -p <pool_name> <seconds> <write|seq|rand> [-b block_size] [-t concurrent_operations] [-k /.../ceph.client.admin.keyring] [-c /.../ceph.conf] [--no-cleanup] [--run-name run_name]
-
-p <pool_name>: 测试存储池名称
-
< seconds>: 测试运行时长,单位为s
-
<write|seq|rand>: 测试读写类型(write:写,seq:顺序读,rand:随机读)
-
-b <block_size>: 测试读写块大小,默认为4MB,默认单位为字节
当存储池为纠删存储类型时,则最小测试文件大小与EC Stripe Width(默认4K)值相等
注:当文件大小不满足该值时,程序会自动调整为EC Stripe Width值 -
-t concurrent_operation: 测试读写并发线程数,默认为16
-
-k /…/ceph.client.admin.keyring: 指定测试ceph.client.admin.keyring配置文件路径
-
-c /…/ceph.conf: 指定测试ceph.conf配置文件路径
-
–no-cleanup: 表示测试完成后不删除测试数据,只对写有效.通常在读测试之前,需要执行写测试生成测试数据之后,再执行读测试
-
–run-name run_name: 表示测试生成的对象名称
注:生成的测试文件可通过命令rados -p {pool_name} cleanup删除
2.2.2 测试模型
在运行这些性能测试前,运行以下命令丢弃所有文件系统缓存:
echo 3 | sudo tee /proc/sys/vm/drop_caches && sudo sync
1M写测试、测试时长10分钟、线程数32:
rados bench -p rbd 600 write -b 1M -t 32 --run-name 1M-write --no-cleanup
1M顺序读、测试时长10分钟、线程数32:
rados bench -p rbd 600 seq -b 1M -t 32 --run-name 1M-seq-read
结果分析:
[root@xxx]# rados bench -p rbd 10 write -b 1M -t 32 --run-name 1M-write --no-cleanup
hints = 1
Maintaining 32 concurrent writes of 1048576 bytes to objects of size 1048576 for up to 10 seconds or 0 objects
Object prefix: benchmark_data_node55_866969
sec Cur ops started finished avg MB/s cur MB/s last lat(s) avg lat(s)
0 0 0 0 0 0 - 0
1 32 1451 1419 1418.91 1419 0.0191834 0.0221416
2 32 2650 2618 1308.88 1199 0.01998 0.0242286
3 32 3950 3918 1305.87 1300 0.0454287 0.0243057
4 32 5268 5236 1308.87 1318 0.0220942 0.0242726
5 32 6450 6418 1283.47 1182 0.00952028 0.0246442
6 32 7783 7751 1291.71 1333 0.0304047 0.0247259
7 32 8917 8885 1269.16 1134 0.0424561 0.0251228
8 32 10103 10071 1258.75 1186 0.0349519 0.0253182
9 32 11369 11337 1259.54 1266 0.18918 0.0252901
10 32 12501 12469 1246.78 1132 0.00946298 0.0254759
Total time run: 10.461089
Total writes made: 12502
Write size: 1048576
Object size: 1048576
Bandwidth (MB/sec): 1195.1
Stddev Bandwidth: 95.1227
Max bandwidth (MB/sec): 1419
Min bandwidth (MB/sec): 1132
Average IOPS: 1195
Stddev IOPS: 95
Max IOPS: 1419
Min IOPS: 1132
Average Latency(s): 0.0262649
Stddev Latency(s): 0.0302529
Max latency(s): 0.852841
Min latency(s): 0.00503798
测试结果取最后几行的值,带宽为Bandwidth (MB/sec)对应的参数值,IOPS为Average IOPS对应参数值,时延为Average Latency(s)对应参数值.
3. 对象存储性能测试
3.1 简介
COSBench 是一款由 Intel 开源,用于对象存储的压测工具。
3.2 系统环境
工具推荐运行在 CentOS 7.0 及其以上版本,ubuntu 环境可能存在预期外的问题。
3.3 影响性能的因素
- 机器核心数:机器核心数较少,开启的 worker 数目较多,容易在上下文切换上产生大量的开销,建议采用 32 或 64 核进行压测。
- 机器网卡:机器流出的流量受网卡限制,大文件的流量压力测试,建议采用万兆以上的网卡。
- 请求网络链路:外网链路质量不一,同时外网下载会产生外网下行流量费用,建议同地域使用内网访问。
- 测试时间:性能测试时,建议测试时间适当延长,获取一个较为稳定的数值。
- 测试环境:程序运行的 JDK 版本,同样也会影响性能。例如测试 HTTPS,低版本客户端的加密算法存在 GCM BUG,随机数发生器可能存在锁等问题。
3.4 COSBench 实践步骤
3.4.1 下载
从 COSBench gitHub 网站下载COSBench 0.4.2.c4.zip压缩包,并在测试机器上进行解压(需要支持unzip)。
3.4.2 安装依赖
# centos执行:
sudo yum install nmap-ncat java curl java-1.8.0-openjdk-devel -y
# ubuntu执行
sudo apt install nmap openjdk-8-jdk
3.4.3 编辑任务配置文件
拷贝s3-config-sample.xml(conf文件夹)为s3-biipoc.xml,修改storage行的对象存储连接信息,包括AK/SK,endpoint等。
备注:endpoint协议建议采用http。
并添加任务配置信息,任务配置主要包含如下五个阶段:
- init 阶段:创建存储桶。
- prepare 阶段:worker 线程,PUT 上传指定大小的对象,用于 main 阶段读取。
- main 阶段:worker 线程混合读写对象,运行指定时长。
- cleanup 阶段,删除生成的对象。
- dispose 阶段:删除存储桶。
示例配置如下:
<?xml version="1.0" encoding="UTF-8" ?>
<workload name="s3-64kb-sample" description="sample benchmark for s3">
<storage type="s3" config="accesskey=PvOcL58LCP3QmIQu;secretkey=pnRlgtkOq3IlEdFS1MiCV00I9ND2od;endpoint=http://oss.biipoc.com" />
<workflow>
<workstage name="init">
<work type="init" workers="1" config="cprefix=s3testqwer;containers=r(1,2)" />
</workstage>
<workstage name="prepare">
<work type="prepare" workers="1" config="cprefix=s3testqwer;containers=r(1,2);objects=r(1,10);sizes=c(64)KB" />
</workstage>
<workstage name="main">
<work name="main" workers="8" runtime="30">
<operation type="read" ratio="80" config="cprefix=s3testqwer;containers=u(1,2);objects=u(1,10)" />
<operation type="write" ratio="20" config="cprefix=s3testqwer;containers=u(1,2);objects=u(11,20);sizes=c(64)KB" />
</work>
</workstage>
<workstage name="cleanup">
<work type="cleanup" workers="1" config="cprefix=s3testqwer;containers=r(1,2);objects=r(1,20)" />
</workstage>
<workstage name="dispose">
<work type="dispose" workers="1" config="cprefix=s3testqwer;containers=r(1,2)" />
</workstage>
</workflow>
</workload>
3.4.4 启动 cosbench 服务
对于centos
sudo bash start-all.sh
对于ubuntu
sudo bash start-driver.sh
&sudo bash start-controller.sh &
3.4.5 提交任务
命令行提交
sudo bash cli.sh submit conf/s3-biipoc.xml
并通过该网址 http://ip:19088/controller/index.html(ip 替换为用户的压测机器 IP)查看执行状态:
界面提交
submit new workloads–选择上传xml文件–提交:
提交后workloads开始运行:
进入view details可以看到五个执行阶段,如下图所示:
3.4.6 查看结果
主要查看以下2个阶段:
- prepare 阶段:1个 worker 线程,上传10个64KB对象。
- main 阶段:8个 worker 线程混合读写对象,运行30秒。
经过以上阶段1和阶段2的性能压测,结果如下:
3.4.7 执行以下命令,停止测试服务
sudo bash stop-all.sh
附录
参考: