本文详细介绍了包括 rados bench、rbd bench、dd 、fio 、vdbench 、filebench 、mdtest 、iozone等测试工具对于 Ceph 集群的性能压测的使用。对于每个工具都提供了压测命令参数、示例命令等使用说明,实现了对 Ceph 块存储、文件存储、对象存储、rados 对象存储等存储类别的性能压测。文中重点阐述了各命令的使用格式、基本功能和参数选择,为用户在 Ceph 环境中进行性能评估提供了实用指南。

一、rados bench

以下基于 v19.2.1 版本进行测试。

用途:

  • 测试 ceph rados 对象存储性能;

1.1、测试配置参数

命令格式:

rados bench $seconds $type [args...]
  • $seconds : 压测运行时间;
  • $type : 压测类型,可选值为 write/seq/rand (分别代表写/连续读/随机读);
  • -p : 指定压测的目标 pool ;
  • -b : 只有当压测类型为 write 时可用,用于设置写入 block 的大小,默认为 4M;
  • -O : 设置写入 object 的大小,默认为 4M(与 -b 参数值相同);
  • -t : 并发数量,默认为 16 ;
  • --no-cleanup : 压测数据后不清理,可用于后续测试读性能;
  • --run-name : 压测任务名(压测任务元信息对象名)。当压测类型为 write 的时,在压测结果后会将压测的配置信息写入该名称的对象中;当压测类型为 seq/rand 时或者启用了 –reuse-bench 参数,则会在压测开始前尝试读取该名称的对象中存储的压测元信息。当执行压测数据清理的时候也会尝试读取其中的压测元信息。其中压测元信息中包括 object_size/finished/prev_pid/op_size。当对一个 pool 执行多个客户端并发压测的时候一定要指定不同的任务名,否则可能无法同时启动多个压测任务,或者会导致压测元信息持久化信息的异常;
  • --no-hints : 默认不指定该参数;
  • --reuse-bench : 默认不指定该参数;
  • --show-time : 默认不指定该参数;
  • --write-object : 只有当压测类型为 write 时可用,用于设置压测写入目标为 object ,默认写入目标为 object;
  • --write-omap : 只有当压测类型为 write 时可用,用于设置压测写入目标为 omap;
  • --write-xattr : 只有当压测类型为 write 时可用,用于设置压测写入目标为 xattr;

1.2、测试命令示例

基础命令:

# 查看命令详情
rados bench --help

# 创建一个名为 tp01 的测试 pool
ceph osd pool create tp01

# 查看池信息
ceph osd pool get tp01 all

# 查看该池占用的资源
rados -p tp01 df

# 清理测试文件
rados -p tp01 cleanup

测试命令:

# 压测写
rados bench 120 write -p tp01 -b 4194304 -O 4194304 -t 16 --show-time --no-cleanup

# 压测顺序读
rados bench 120 seq -p tp01 -t 16 --show-time

# 压测随机读
rados bench 120 rand -p tp01 -t 16 --show-time

# 清理压测数据
rados cleanup -p tp01

二、rbd bench

以下基于 v19.2.1 版本进行测试。

用途:

  • 测试块存储性能;

2.1、测试配置参数

命令格式:

rbd bench [-p/--pool <pool>] [--namespace <namespace>] [--image <image>]
[--io-size <io-size>] [--io-threads <io-threads>]
[--io-total <io-total>] [--io-pattern <io-pattern>]
[--rw-mix-read <rw-mix-read>] --io-type <io-type>
<image-spec>
  • -p/--pool : 指定压测的 pool ;
  • --namespace : 指定压测的 namespace ;
  • --image : 指定压测的 image ;
  • --io-size : 每次操作 IO 的大小,可选值 < 4G , 默认为 4K ;
  • --io-threads : 默认为 16 ;
  • --io-total : 默认为 1G ;
  • --io-pattern : 执行 IO 的模式,用于设置多线程情况下每个线程操作数据的起始点,可选值为 rand/seq/full-seq (随机的/连续的/完全连续的) ,默认为 seq 。rand 模式下随机设定每个线程的数据起始点。seq 模式下按照线程数量分配 image 总大小,分配给每个线程相互独立的数据范围,设置每个线程的数据起始点,实现每个线程操作自己范围内的数据。full-seq 模式下,每个线程分配的起始点为分别是 0io-size , 1io-size, 2*io-size 等;
  • --rw-mix-read : 设置读写操作的比例,这里的值为读操作的比例,可选值 <= 100 , 默认为 50 。 这里采用的概率范围计算方法,计算规则为每次执行压测的时候获取 0 到 100 以内的数字,如果获取的数字小于该值则执行读操作,如果获取的数字大于等于该值则执行写操作,通常由于 100 以内的每个数字出现的概率相同,所以可以按照数字的多少来划分概率;
  • --io-type : 压测类型,可选值为 read/write/readwrite(rw) (读/写/读写混合);
  • image-spec :

rand

seq

full-seq

2.2、测试命令示例

基础命令:

# 查看命令详情
rbd help bench

# 创建一个名为 tp02 的 pool
ceph osd pool create tp02

# 初始化名为 tp02 的 pool
rbd pool init tp02

# 在 tp02 的 pool 中创建一个名为 img01 的 image, 并限制其大小为 50G
rbd create tp02/img01 --size 50G

# 映射 image 到本机
rbd map tp02/img01

# 列出所有的 pool
ceph osd lspools

# 列出 tp02 中的所有 image
rbd ls -p tp02

# 列出所有镜像的映射信息
rbd showmapped

# 查看镜像信息
rbd info tp02/img01

# 查看镜像容量
rbd --pool tp02 --image img01 du

测试命令:

# 随机读
rbd bench --pool tp02 --image img01 --io-size 4K --io-threads 16 --io-total 16G --io-pattern rand --io-type read

# 随机写
rbd bench --pool tp02 --image img01 --io-size 4K --io-threads 16 --io-total 16G --io-pattern rand --io-type write

# 顺序读
rbd bench --pool tp02 --image img01 --io-size 4K --io-threads 16 --io-total 16G --io-pattern seq --io-type read

# 顺序写
rbd bench --pool tp02 --image img01 --io-size 4K --io-threads 16 --io-total 16G --io-pattern seq --io-type write

# 随机比例读写: 读:80%,写:20%
rbd bench --pool tp02 --image img01 --io-size 4K --io-threads 16 --io-total 16G --io-pattern rand --io-type readwrite --rw-mix-read 80

# 随机比例读写: 读:20%,写:80%
rbd bench --pool tp02 --image img01 --io-size 4K --io-threads 16 --io-total 16G --io-pattern rand --io-type readwrite --rw-mix-read 20

# 顺序比例读写: 读:80%,写:20%
rbd bench --pool tp02 --image img01 --io-size 4K --io-threads 16 --io-total 16G --io-pattern seq --io-type readwrite --rw-mix-read 80

# 顺序比例读写: 读:20%,写:80%
rbd bench --pool tp02 --image img01 --io-size 4K --io-threads 16 --io-total 16G --io-pattern seq --io-type readwrite --rw-mix-read 20

三、dd

用途:

  • 测试裸设备存储性能;
  • 测试块存储性能;
  • 测试文件存储性能;

3.1、测试配置参数

命令格式:

dd [OPERAND]...
  • bs : 每次操作的字节数,该值会覆盖 ibs 和 obs , 默认为 512 ;
  • cbs : 每次转换的字节数;
  • conv : 根据逗号分隔的符号列表转换文件;
  • count : 操作的块总数量;
  • ibs : 每次读取最多的字节数,默认为 512 ;
  • if : 从文件中读取,而不是从标准输入中读取;
  • iflag : 读操作的 flag 列表,以逗号分隔;
  • obs : 每次写入字节数,默认为 512 ;
  • of : 写入到文件,而不是写入到标准输出;
  • oflag : 写操作的 flag 列表,以逗号分隔 ;
  • seek : 在输出开始时跳过 N 个 obs 大小的块;
  • skip : 在输入开始时跳过 N 个 ibs 大小的块;
  • status : 打印到标准错误的级别信息,none 仅展示错误消息, noxfer 阻止最终传输统计信息, progress 显示周期性传输统计信息;

命令相关的 flag 参数如下:

  • append : 追加模式,仅对输出有意义,建议使用 conv=notrunc ;
  • direct : 使用直接 I/O 操作数据;
  • directory : 仅支持操作目录;
  • dsync : 使用同步 I/O 操作数据;
  • sync : 使用同步 I/O 操作数据,也适用于元数据;
  • fullblock : 累积完整的输入块,仅限 iflag ;
  • nonblock : 使用非阻塞 I/O ;
  • noatime : 不更新访问时间 ;
  • nocache : 请求丢弃缓存。另见 oflag=sync ;
  • noctty : 不从文件分配控制终端 ;
  • nofollow : 不跟随符号链接;
  • count_bytes : 将 ‘count=N’ 视为字节计数,仅限 iflag ;
  • skip_bytes : 将 ‘skip=N’ 视为字节计数,仅限 iflag ;
  • seek_bytes : 将 ‘seek=N’ 视为字节计数,仅限 oflag ;

命令相关的 conv 参数如下:

  • ascii : 从 EBCDIC 到 ASCII ;
  • ebcdic : 从 ASCII 到 EBCDIC ;
  • ibm : 从 ASCII 到替代 EBCDIC ;
  • block : 用空格填充以换行符结尾的记录到 cbs 大小;
  • unblock : 用换行符替换 cbs 大小记录中的尾随空格;
  • lcase : 将大写字母转换为小写字母;
  • ucase : 将小写字母转换为大写字母;
  • sparse : 尝试在输出中为 NUL 输入块进行跳过而不是写入;
  • swab : 交换每对输入字节;
  • sync : 用 NUL 填充每个输入块到 ibs 大小;与 block 或 unblock 一起使用时,用空格而不是 NUL 填充;
  • excl : 如果输出文件已存在则失败;
  • nocreat : 不创建输出文件;
  • notrunc : 不截断输出文件;
  • noerror : 读取错误后继续;
  • fdatasync : 在完成前物理写入输出文件数据;
  • fsync : 在完成前物理写入输出文件数据,也写入元数据;

3.2、测试命令示例

通常 dd 命令可以与 time 命令结合使用,以便于获取 dd 执行的耗时信息。

基础命令:

# 查看 sdc 盘支持的最大 I/O 块大小
cat /sys/block/sdc/queue/max_sectors_kb

# 清除缓存
sync; echo 3 > /proc/sys/vm/drop_caches

3.2.1、裸设备性能测试

测试命令:

# 对 /dev/sdc 裸设备进行写性能测试
time dd if=/dev/zero of=/dev/sdc bs=1M count=50000 oflag=direct status=progress

# 对 /dev/sdc 裸设备进行读性能测试
time dd if=/dev/sdc of=/dev/null bs=1M count=50000 iflag=direct status=progress

3.2.2、块存储性能测试

基础命令:

# 查看硬盘信息
lsblk

# 硬盘分区
sudo fdisk /dev/sdc

测试命令:

# 对 /dev/sdc1 块设备进行写性能测试
time dd if=/dev/zero of=/dev/sdc1 bs=1M count=50000 oflag=direct status=progress

# 对 /dev/sdc 块设备进行读性能测试
time dd if=/dev/sdc1 of=/dev/null bs=1M count=50000 iflag=direct status=progress

3.2.3、文件存储性能测试

基础命令:

# 查看硬盘信息
lsblk

# 硬盘分区
sudo fdisk /dev/sdc

# 格式化分区
mkfs.ext4 /dev/sdc1

# 挂载分区
mkdir /mnt/data
mount /dev/sdc1 /mnt/data

# 自动挂载,可以编辑/etc/fstab 文件,添加一条挂载分区的记录
/dev/sdc1 /mnt/data ext4 defaults 0 0

测试命令:

# 写性能测试
dd if=/dev/zero of=/mnt/data/testfile bs=1M count=50000 oflag=direct status=progress

# 读性能测试
dd if=/mnt/data/testfile of=/dev/null bs=1M count=50000 iflag=direct status=progress

# 写性能测试
# fdatasync 表示每次写入数据后,将数据同步到磁盘中
# notrunc 表示不截断输出文件
dd if=/dev/zero of=/mnt/data/testfile bs=1M count=50000 oflag=direct conv=fdatasync,notrunc status=progress

# 写限速
dd if=/dev/zero bs=1M count=100000 | pv -L 2M | dd of=/mnt/data/testfile oflag=direct status=progress

# 读限速
dd if=/mnt/data/testfile bs=1M count=500000 iflag=direct | pv -L 8M | dd of=/dev/null status=progress

四、fio

用途:

  • 测试裸设备存储性能;
  • 测试块存储性能;
  • 测试文件存储性能;
  • 测试对象存储性能;
  • 测试 ceph rados 对象存储性能;

以下介绍基于 fio 3.40 版本。

软件环境及安装:

# 安装环境依赖
dnf install -y ceph-common librbd1 librbd-devel curl openssl openssl-devel

# 编译安装
wget https://github.com/axboe/fio/archive/refs/tags/fio-3.40.tar.gz
tar -zxvf fio-3.40.tar.gz
cd fio-fio-3.40
./configure
make
make install

4.1、测试配置参数

命令格式:

fio [options] [job options] <job file(s)>
  • --debug : 启用调试日志。可选参数为一个或多个。process,file,io,mem,blktrace,verify,random,parse,diskutil,job,mutex,profile,time,net,rate,compress,steadystate,helperthread,zbd ;
  • --parse-only : 仅解析选项,不启动任何 IO ;
  • --merge-blktrace-only : 仅合并 blktrace,不启动任何 IO ;
  • --output : 将输出写入文件;
  • --bandwidth-log : 生成聚合带宽日志;
  • --minimal : 最小化(简洁)输出;
  • --output-format=type : 输出格式,可选值为 terse/json/json+/normal ;
  • --terse-version=type : 设置简洁版本输出格式,可选值为 2/3/4 ,默认为 3 ;
  • --cpuclock-test : 执行 CPU 时钟的测试/验证;
  • --crctest=[type] : 测试校验和函数的速度;
  • --cmdhelp=cmd : 打印命令帮助,all 表示所有命令;
  • --enghelp=engine : 打印 ioengine 帮助,或列出可用的 ioengine ;
  • --enghelp=engine,cmd : 打印 ioengine 命令的帮助;
  • --showcmd : 将作业文件转换为命令行选项;
  • --eta=when : 何时打印 ETA 估计,可选值为 always/never/auto ;
  • --eta-newline=t : 每经过 t 时间强制换行;
  • --status-interval=t : 每经过 t 时间强制完整状态转储;
  • --readonly : 开启安全只读检查,防止写入;
  • --section=name : 仅运行作业文件中指定的部分,可以指定多个部分;
  • --alloc-size=kb : 将 smalloc 池设置为此大小,单位为 kb , 默认为 16384 ;
  • --warnings-fatal : fio 解析器警告为致命错误;
  • --max-jobs=nr : 支持的最大线程/进程数;
  • --server=args : 启动后端 fio 服务器;
  • --daemonize=pidfile : 后台运行 fio 服务器,将 pid 写入文件;
  • --client=hostname : 与远程后端 fio 服务器在主机名通信;
  • --remote-config=file : 告诉 fio 服务器加载此本地作业文件;
  • --idle-prof=option : 报告系统或每个 CPU 的空闲情况(option=system,percpu),或仅运行单位工作校准(option=calibrate);
  • --inflate-log=log : 解压并输出压缩日志;
  • --trigger-file=file : 当文件存在时执行触发命令;
  • --trigger-timeout=t : 在此时间执行触发;
  • --trigger=cmd : 将此命令设置为本地触发器;
  • --trigger-remote=cmd : 将此命令设置为远程触发器;
  • --aux-path=path : 使用此路径存储 fio 状态生成的文件;

支持的 io engines 列表: (使用 fio --enghelp 命令列出, 可使用 fio --enghelp=$name 命令列出对应 io engine 的参数,部分参数解释通过 AI 分析,请谨慎参考)

  • cpuio : 专门用于测试 CPU 性能的 I/O 引擎。它不涉及任何实际的磁盘或网络 I/O 操作,而是通过执行计算密集型任务来模拟 I/O 负载。这种引擎通常用于评估 CPU 的处理能力和多线程性能;
  • mmap : 通过内存映射文件进行 I/O 操作。这种方法可以直接通过内存访问文件数据,适用于需要高速缓存和内存操作的测试;
  • sync : 使用标准的同步 I/O 系统调用(如 read() 和 write())。这是最基本的 I/O 引擎,适用于普通的磁盘 I/O 性能测试;
  • psync : 使用 POSIX 同步 I/O 系统调用。这种引擎使用 pread() 和 pwrite(),允许进行位置指定的同步 I/O 操作;
  • vsync : 类似于 psync,但使用 vmsplice() 来进行数据传输,适用于需要高效数据移动的场景;
  • pvsync : 类似于 psync,但使用 preadv() 和 pwritev() 系统调用,这些调用允许进行向量化的读写操作,即一次操作可以处理多个非连续的内存块;
  • pvsync2 : 这是 pvsync 的改进版本,使用更现代的 preadv2() 和 pwritev2() 系统调用,支持额外的标志和功能,如 RWF_NOWAIT,可以提高异步处理能力;
  • null : 一个特殊的 I/O 引擎,它实际上不执行任何 I/O 操作。这可以用来测试 fio 本身的开销或用作控制组;
  • net : 用于网络 I/O 性能测试。这种引擎可以模拟网络数据发送和接收,用于评估网络设备和协议的性能;
  • netsplice : 使用 splice() 和网络套接字结合的方式进行数据传输。这种方法可以直接在内核中转移数据到网络套接字,减少用户空间和内核空间之间的数据复制;
  • ftruncate : 使用 ftruncate() 系统调用来改变文件的大小。这种引擎主要用于测试文件系统如何处理文件大小的变化,特别是在文件系统扩展和收缩时的性能;
  • filecreate : 专注于文件创建操作。使用这个引擎可以测试文件系统创建新文件的性能,这对于评估文件系统的元数据操作性能非常重要;
  • filestat : 用于测试文件状态操作,如使用 stat() 系统调用。这可以帮助评估文件系统在处理文件元数据查询时的效率;
  • filedelete : 用于测试文件删除操作的性能。它可以帮助用户了解在特定存储系统上删除文件所需的时间和资源消耗;
  • dircreate : 用于测试目录创建操作的性能。使用这个引擎可以测量创建新目录所需的时间;
  • dirstat : 用于测试获取目录状态的操作性能,比如读取目录中的文件列表;
  • dirdelete : 用于测试删除目录的性能;
  • exec : 允许fio执行外部命令或脚本,这可以用来测试系统在执行特定命令或脚本时的I/O性能;
  • posixaio : 使用 POSIX 异步 I/O 接口。这种引擎在多平台上提供异步 I/O 功能,但在 Linux 上通常不如 libaio 高效;
  • falloc : 使用 fallocate() 系统调用来预分配文件空间。这种方法可以在文件实际写入之前确保空间被分配,用于测试文件系统如何处理空间分配请求;
  • e4defrag : 专门用于测试 ext4 文件系统的碎片整理操作。这可以帮助评估 ext4 文件系统在长时间运行后,文件碎片整理对性能的影响;
  • splice : 使用 Linux 的 splice() 系统调用来移动数据。这种方法可以在两个文件描述符之间直接传输数据,减少数据复制操作的开销;
  • mtd : 针对内存技术设备(Memory Technology Device)的 I/O 引擎。MTD 设备通常是嵌入式存储设备,如闪存,不具备常见的块设备接口。这个引擎允许 fio 直接与这类设备进行交互,测试其性能,特别是在嵌入式系统或 IoT 设备中非常有用;
  • sg : 使用 SCSI generic (sg) 接口进行 I/O 操作的引擎。这个引擎允许 fio 直接与 SCSI 设备进行交互,绕过传统的块设备层。这对于需要直接评估 SCSI 命令性能或进行低级别 SCSI 测试的场景非常有用;
  • io_uring : 利用 Linux 的 io_uring 接口进行 I/O 操作。这是一种现代的异步 I/O 接口,提供了比传统 AIO 更高的性能和更低的 CPU 使用率;
  • io_uring_cmd : 擎利用了Linux的io_uring接口,这是一种高效的异步I/O执行方式。io_uring_cmd引擎可以帮助开发者测试和优化使用io_uring接口的应用程序的性能;
  • libaio : 利用 Linux 的异步 I/O 子系统(AIO)。这种引擎可以在不阻塞应用程序的情况下提交和完成 I/O,适用于高性能和高并发的 I/O 测试;
  • rdma : 使用远程直接内存访问(RDMA)技术进行数据传输。这种引擎适用于需要高性能网络通信的场景,如数据中心内部或高性能计算环境;
  • rados : 专为测试 Ceph RADOS 存储集群设计的引擎。它直接与 Ceph 的 RADOS 层交互,用于评估 Ceph 集群的性能;
  • rbd : 针对 Ceph 块设备(RBD)的 I/O 引擎。它允许直接对 Ceph 块存储进行性能测试,适用于评估虚拟化环境中的存储性能;
  • http : 使fio能够执行HTTP请求,从而测试HTTP服务器的性能。这包括了解服务器处理请求的能力,以及在高负载下的稳定性和响应时间;

相关参数: (使用 fio --cmdhelp=all 命令列出)

description             : 文本工作描述
name : 此工作的名称
wait_for : 此工作在开始前需要等待的工作名称
filename : 用于工作负载的文件
lockfile : 执行 IO 时的锁文件
directory : 存储文件的目录
filename_format : 覆盖默认的 $jobname.$jobnum.$filenum 命名
unique_filename : 对于网络客户端,文件名前缀为源 IP
opendir : 递归添加此目录及其下的文件
rw : IO 方向,可选值为 read/write/trim/randread/randwrite/randtrim/rw/readwrite/randrw/trimwrite ,默认值为 read
bs : 块大小单位
ba : IO 块偏移对齐
bsrange : 设置块大小范围(比 bs 更详细)
bssplit : 设置特定的块大小混合
bs_unaligned : 不对 IO 缓冲区大小进行扇区对齐
randrepeat : 使用可重复的随机 IO 模式
randseed : 设置随机生成器的种子值
norandommap : 接受可能的重复随机块
ignore_error : 设置要忽略的特定错误列表
rw_sequencer : IO 偏移生成器修饰符
ioengine : 使用的 IO 引擎
iodepth : 保持在运行中的 IO 缓冲区数量
iodepth_batch : 一次提交的 IO 缓冲区数量
iodepth_batch_complete_min: 一次检索的最小 IO 缓冲区数量
iodepth_batch_complete_max: 一次检索的最大 IO 缓冲区数量
iodepth_low : 排队深度的低水位线
serialize_overlap : 等待重叠的在运行 IO 完成
io_submit_mode : IO 提交和完成的方式
size : 设备或文件的总大小
io_size : 要执行的 I/O 总大小
fill_device : 写入直到发生 ENOSPC 错误
filesize : 单个文件的大小
file_append : IO 将从文件末尾开始
offset : 从此偏移开始 IO
offset_increment : 从一个偏移到下一个偏移的增量
offset_align : 从此偏移对齐开始 IO
number_ios : 在此 IO 数量后强制完成工作
random_generator : 使用的随机数生成器类型
random_distribution : 随机偏移分布生成器
percentage_random : 顺序/随机混合中应为随机的百分比
allrandrepeat : 对所有内容使用可重复的随机数
nrfiles : 在此文件数量之间分配工作负载
file_service_type : 如何选择下一个要服务的文件
openfiles : 同时保持打开的文件数量
fallocate : 布局文件时是否进行预分配
fadvise_hint : 使用 fadvise() 向内核建议 IO 模式
fsync : 每给定块数为写入发出 fsync
fdatasync : 每给定块数为写入发出 fdatasync
write_barrier : 每第 N 次写入作为屏障写入
sync_file_range : 使用 sync_file_range()
direct : 使用 O_DIRECT IO(否定缓冲)
atomic : 使用带 O_DIRECT 的原子 IO(意味着 O_DIRECT)
buffered : 使用缓冲 IO(否定直接)
sync : 对缓冲写入使用 O_SYNC
overwrite : 写入时,设置是否覆盖当前数据
loops : 运行工作的次数
numjobs : 复制此工作的次数
startdelay : 仅在此时间段过去后开始工作
runtime : 在经过此时间后停止工作负载
time_based : 继续运行直到达到运行时间/超时
verify_only : 验证先前写入的数据仍然有效
ramp_time : 在测量性能前的加速时间
clocksource : 使用的时间源类型
mem : IO 缓冲区的支持类型
verify : 验证写入的数据
do_verify : 写入后运行验证阶段
verify_interval : 每 N 字节存储验证缓冲区头
verify_offset : 将验证头位置偏移 N 字节
verify_pattern : IO 缓冲区的填充模式
verify_fatal : 在单个验证失败时退出,不继续
verify_dump : 在失败时转储良好和坏块的内容
verify_async : 使用的异步验证器线程数量
verify_backlog : 写入此数量的块后进行验证
verify_backlog_batch : 验证此数量的 IO 块
experimental_verify : 启用实验性验证
verify_state_load : 加载验证终止状态
verify_state_save : 在终止时保存验证状态
trim_percentage : 要修剪(即丢弃)的验证块数量
trim_verify_zero : 验证修剪(即丢弃)的块是否返回为零
trim_backlog : 写入此数量的块后进行修剪
trim_backlog_batch : 修剪此数量的 IO 块
write_iolog : 将 IO 模式存储到文件
read_iolog : 从文件回放 IO 模式
read_iolog_chunked : 分块解析 IO 模式
replay_no_stall : 尽可能快地回放 IO 模式文件而不暂停
replay_redirect : 将所有 I/O 重放到此设备,无论跟踪设备如何
replay_scale : 将偏移对齐到此块大小
replay_align : 按此因子缩小偏移
replay_time_scale : 缩放重放事件的时间
replay_skip : 跳过某些 IO 类型(读、写、修剪、刷新)
merge_blktrace_file : 合并的 blktrace 输出文件名
merge_blktrace_scalars : 缩放每个跟踪的百分比
merge_blktrace_iters : 每个跟踪运行的迭代次数
exec_prerun : 在运行工作之前执行此文件
exec_postrun : 在运行工作之后执行此文件
ioscheduler : 在支持设备上使用此 IO 调度程序
zonemode : zonesize、zonerange 和 zoneskip 参数的模式
zonesize : 每个区域读取的数据量
zonerange : 给出 IO 区域的大小
zoneskip : IO 区域之间的空间
read_beyond_wp : 允许读取超出区域写入指针
max_open_zones : 将随机写入限制为 SMR 驱动器的指定顺序区域数量
zone_reset_threshold : 分区块设备重置阈值
zone_reset_frequency : 分区块设备区域重置频率(以 HZ 为单位)
lockmem : 锁定此内存量(每个工作者)
rwmixread : 混合工作负载中读取的百分比
rwmixwrite : 混合工作负载中写入的百分比
nice : 设置工作 CPU nice
prio : 设置工作 IO 优先级值
prioclass : 设置工作 IO 优先级类
thinktime : IO 缓冲区之间的空闲时间(微秒)
thinktime_spin : 通过旋转此时间量(微秒)开始思考时间
thinktime_blocks : 'thinktime' 之间的 IO 缓冲区周期
rate : 设置带宽速率
rate_min : 工作必须达到此速率,否则将关闭
rate_process : 控制如何管理速率 IO 的进程
rate_cycle : 速率限制的窗口平均值(毫秒)
rate_ignore_thinktime : 速率 IO 忽略思考时间设置
rate_iops : 将 IO 使用限制为此数量的 IO 操作/秒
rate_iops_min : 工作必须达到此速率,否则将关闭
max_latency : 最大容忍的 IO 延迟(微秒)
latency_target : 支持此延迟的最大队列深度
latency_window : 维持 latency_target 的时间
latency_percentile : IO 的百分比必须低于 latency_target
latency_run : 不断调整队列深度以匹配 latency_target
invalidate : 在运行工作之前使缓冲区/页面缓存失效
write_hint : 设置预期的写入寿命
create_serialize : 序列化创建工作文件
create_fsync : 创建后 fsync 文件
create_on_open : 在打开进行 IO 时创建文件
create_only : 仅执行文件创建阶段
allow_file_create : 允许 fio 创建文件,如果它们不存在
allow_mounted_write : 允许写入已挂载的分区
pre_read : 在开始正式测试之前预读文件
cpumask : CPU 亲和性掩码
cpus_allowed : 设置允许的 CPU
cpus_allowed_policy : cpus_allowed 的分配策略
numa_cpu_nodes : NUMA CPU 节点绑定
numa_mem_policy : NUMA 内存策略设置
end_fsync : 在工作结束时包含 fsync
fsync_on_close : 关闭时 fsync 文件
unlink : 工作完成后取消链接创建的文件
unlink_each_loop : 在工作中的每个循环完成后取消链接创建的文件
exitall : 当一个工作退出时终止所有工作
exit_what : 对 exitall 的细粒度控制
exitall_on_error : 当一个工作出错退出时终止所有工作
stonewall : 在此工作和之前的工作之间插入硬屏障
new_group : 标记新组的开始(用于报告)
thread : 使用线程而不是进程
per_job_logs : 在生成的日志文件中包含工作编号与否
write_bw_log : 在运行期间写入带宽日志
bwavgtime : 计算带宽的时间窗口(毫秒)
write_lat_log : 在运行期间写入延迟日志
write_iops_log : 在运行期间写入 IOPS 日志
iopsavgtime : 计算 IOPS 的时间窗口(毫秒)
log_avg_msec : 在此时间段内平均 bw/iops/lat 日志
log_hist_msec : 以此时间值的频率转储完成延迟直方图
log_hist_coarseness : 范围 [0,6] 的整数。较高的粗糙度输出每个样本的直方图箱数较少。这些的箱数分别为 [1216, 608, 304, 152, 76, 38, 19]。
write_hist_log : 在运行期间写入延迟直方图日志
log_max_value : 在窗口中记录最大样本而不是平均值
log_offset : 为每个日志条目包含 IO 的偏移
log_compression : 以此大小的压缩块记录
log_compression_cpus : 将日志压缩限制在这些 CPU 上
log_store_compressed : 以压缩格式存储日志
log_unix_epoch : 在日志文件中使用 Unix 时间
block_error_percentiles : 记录修剪块错误并制作直方图
group_reporting : 按组进行报告
stats : 启用统计数据收集
zero_buffers : 将 IO 缓冲区初始化为全零
refill_buffers : 在每次 IO 提交时重新填充 IO 缓冲区
scramble_buffers : 在每次 IO 提交时稍微扰乱缓冲区
buffer_pattern : IO 缓冲区的填充模式
buffer_compress_percentage: 缓冲区的可压缩性(大约)
buffer_compress_chunk : 缓冲区中可压缩区域的大小
dedupe_percentage : 可去重的缓冲区百分比
clat_percentiles : 启用完成延迟百分位数的报告
lat_percentiles : 启用 IO 延迟百分位数的报告
slat_percentiles : 启用提交延迟百分位数的报告
percentile_list : 指定要报告的完成延迟和块错误的自定义百分位数列表
significant_figures : 输出格式设置为正常的有效数字
disk_util : 记录磁盘利用率统计
gtod_reduce : 大大减少 gettimeofday() 调用的数量
disable_lat : 禁用延迟数字
disable_clat : 禁用完成延迟数字
disable_slat : 禁用提交延迟数字
disable_bw_measurement: 禁用带宽记录
gtod_cpu : 在此 CPU 上设置专用的 gettimeofday() 线程
unified_rw_reporting : 统一跨数据方向的报告
continue_on_error : 在 IO 期间的非致命错误上继续
error_dump : 转储每个错误的信息
profile : 选择特定的内置性能测试
cgroup : 将工作添加到此名称的 cgroup
cgroup_nodelete : 工作完成后不删除 cgroup
cgroup_weight : 使用给定的 cgroup 权重
uid : 使用此用户 ID 运行工作
gid : 使用此组 ID 运行工作
kb_base : 数据量的单位前缀解释(IEC 和 SI)
unit_base : 结果摘要数据的位倍数(字节为 8,位为 1)
hugepage-size : 使用大页时,指定每页的大小
flow_id : 使用的流索引 ID
flow : 此工作的流控制权重
flow_watermark : 流控制的高水位线。此选项应为所有具有非零流的线程设置为相同值。
flow_sleep : 在被流控制机制阻止后休眠的微秒数
steadystate : 定义判断工作何时达到稳态的标准和限制
steadystate_duration : 在达到稳态指定持续时间后停止工作负载
steadystate_ramp_time : 数据收集的延迟时间,用于稳态工作终止测试

4.2、测试命令示例

4.2.1、裸设备/块存储性能测试

测试命令(使用 libaio 引擎):

官方示例的 fio 文件: https://github.com/axboe/fio/blob/fio-3.40/examples/aio-read.fio

# 随机读 IOPS
fio --name=rand-read-iops \
--direct=1 \
--iodepth=128 \
--rw=randread \
--ioengine=libaio \
--bs=4k \
--size=1G \
--numjobs=1 \
--runtime=1000 \
--filename=/dev/sdc \
--group_reporting

# 随机写 IOPS
fio --name=rand-write-iops \
--direct=1 \
--iodepth=128 \
--rw=randwrite \
--ioengine=libaio \
--bs=4k \
--size=1G \
--numjobs=1 \
--runtime=1000 \
--filename=/dev/sdc \
--group_reporting

# 顺序读吞吐
fio --name=seq-read-bw \
--direct=1 \
--iodepth=64 \
--rw=read \
--ioengine=libaio \
--bs=1m \
--size=1G \
--numjobs=1 \
--runtime=1000 \
--filename=/dev/sdc \
--group_reporting

# 顺序写吞吐
fio --name=seq-write-bw \
--direct=1 \
--iodepth=64 \
--rw=write \
--ioengine=libaio \
--bs=1m \
--size=1G \
--numjobs=1 \
--runtime=1000 \
--filename=/dev/sdc \
--group_reporting

# 随机读时延
fio --name=rand-read-latency \
--direct=1 \
--iodepth=1 \
--rw=randread \
--ioengine=libaio \
--bs=4k \
--size=1G \
--numjobs=1 \
--filename=/dev/sdc \
--group_reporting

# 随机写时延
fio --name=rand-write-latency \
--direct=1 \
--iodepth=1 \
--rw=randwrite \
--ioengine=libaio \
--bs=4k \
--size=1G \
--numjobs=1 \
--filename=/dev/sdc \
--group_reporting

ceph 块存储测试命令(使用 rbd 引擎):

官方示例的 fio 文件: https://github.com/axboe/fio/blob/fio-3.40/examples/rbd.fio

相关参数( rbd 引擎):

  • clustername : Ceph 的集群名称;
  • pool : 托管 RBD 引擎的 RBD 的池名称;
  • rbdname : RBD 引擎的 RBD 名称,对应镜像名称;
  • clientname : 访问 RBD 引擎的 RBD 的 Ceph 客户端名称;
  • busy_poll : 完成任务后使用 busy pool ,而不是使用 sleeping ;
# 随机读 IOPS
fio --name=rand-read \
--direct=1 \
--iodepth=64 \
--rw=randread \
--ioengine=rbd \
--clientname=admin \
--pool=tp03 \
--rbdname=img01 \
--bs=4k \
--size=1G \
--numjobs=1 \
--runtime=1000 \
--group_reporting

# 随机写 IOPS
fio --name=rand-write \
--direct=1 \
--iodepth=64 \
--rw=randwrite \
--ioengine=rbd \
--clientname=admin \
--pool=tp03 \
--rbdname=img01 \
--bs=4k \
--size=1G \
--numjobs=1 \
--runtime=1000 \
--group_reporting

# 顺序读吞吐
fio --name=seq-read \
--direct=1 \
--iodepth=64 \
--rw=read \
--ioengine=rbd \
--clientname=admin \
--pool=tp03 \
--rbdname=img01 \
--bs=4m \
--size=1G \
--numjobs=1 \
--runtime=1000 \
--group_reporting

# 顺序写吞吐
fio --name=seq-write \
--direct=1 \
--iodepth=64 \
--rw=write \
--ioengine=rbd \
--clientname=admin \
--pool=tp03 \
--rbdname=img01 \
--bs=4m \
--size=1G \
--numjobs=1 \
--runtime=1000 \
--group_reporting

4.2.2、文件存储性能测试

基础命令:

# 挂载特定文件系统到 /mnt/data 目录

测试命令(使用 libaio 引擎):

# 随机读
fio --name=rand-read \
--direct=1 \
--iodepth=1 \
--rw=randread \
--ioengine=libaio \
--bs=4k \
--size=5G \
--numjobs=1 \
--runtime=1000 \
--directory=/mnt/data \
--nrfiles=64 \
--group_reporting

# 随机写
fio --name=rand-write \
--direct=1 \
--iodepth=1 \
--rw=randwrite \
--ioengine=libaio \
--bs=4k \
--size=5G \
--numjobs=1 \
--runtime=1000 \
--directory=/mnt/data \
--nrfiles=64 \
--group_reporting

# 顺序读
fio --name=seq-read \
--direct=1 \
--iodepth=1 \
--rw=read \
--ioengine=libaio \
--bs=4m \
--size=10G \
--numjobs=1 \
--runtime=1000 \
--directory=/mnt/data \
--nrfiles=64 \
--group_reporting

# 顺序写
fio --name=seq-write \
--direct=1 \
--iodepth=1 \
--rw=write \
--ioengine=libaio \
--bs=4m \
--size=10G \
--numjobs=1 \
--runtime=1000 \
--end_fsync=1 \
--directory=/mnt/data \
--nrfiles=64 \
--group_reporting

4.2.3、对象存储性能测试

Ceph 相关命令:

ceph config dump
ceph config set mgr mgr/dashboard/ALERTMANAGER_API_HOST $val
ceph config set mgr mgr/dashboard/GRAFANA_API_URL $val
ceph config set mgr mgr/dashboard/PROMETHEUS_API_HOST $val

# 启用对象存储
ceph mgr module enable rgw
ceph orch apply rgw foo

# 创建 s3 的兼容用户
radosgw-admin user create --uid s3user --display-name "Ceph S3 User Demo"

# 查询 ceph 中 rgw 对应的用户信息(获取 access_key 和 secret_key)
radosgw-admin user info --uid s3user

官方示例的 fio 文件: https://github.com/axboe/fio/blob/fio-3.40/examples/http-s3.fio

相关参数( http 引擎):

  • https : 启用 https ;
  • http_host : 主机名 (S3 存储桶);
  • http_user : HTTP 用户名;
  • http_pass : HTTP 密码;
  • http_s3_key : S3 密钥;
  • http_s3_keyid : S3 密钥 ID ;
  • http_swift_auth_token : OpenStack Swift 认证令牌;
  • http_s3_region : S3 区域;
  • http_s3_sse_customer_key : S3 SSE 客户密钥;
  • http_s3_sse_customer_algorithm : S3 SSE 客户算法;
  • http_s3_storage_class : S3 存储类;
  • http_mode : 是否使用 WebDAV、Swift 或 S3 ;
  • http_verbose : 增加 http 引擎的详细程度;

测试命令(使用 http 引擎):

# 创建


# 删除

4.2.4、ceph rados 对象存储性能测试

官方示例的 fio 文件: https://github.com/axboe/fio/blob/fio-3.40/examples/rados.fio

相关参数( rados 引擎):

  • clustername : Ceph 集群名称;
  • pool : 要进行基准测试的 Ceph 池名称;
  • clientname : 访问 RADOS 引擎的 Ceph 客户端名称;
  • conf : Ceph 配置文件的路径;
  • busy_poll : 完成后 busy pool ,而不是使用 sleeping ;
  • touch_objects : 在启动时触碰(创建)对象;

测试命令(使用 rados 引擎): 无论是顺序/随机读,还是顺序/随机写,fio 内部实现的 rados 的操作都只对应同一个读写操作,分别是:rados_aio_write 和 rados_aio_read 。

# 读测试
fio --name=rand-read \
--direct=1 \
--iodepth=32 \
--rw=read \
--ioengine=rados \
--pool=tp04 \
--clientname=admin \
--conf=/etc/ceph/ceph.conf \
--bs=4m \
--size=1G \
--numjobs=1 \
--runtime=1000 \
--nrfiles=32 \
--group_reporting

# 写测试
fio --name=rand-read \
--direct=1 \
--iodepth=32 \
--rw=write \
--ioengine=rados \
--pool=tp04 \
--clientname=admin \
--conf=/etc/ceph/ceph.conf \
--bs=4m \
--size=1G \
--numjobs=1 \
--runtime=1000 \
--nrfiles=32 \
--group_reporting

五、vdbench

用途:

  • 测试块存储性能;
  • 测试文件存储性能;

5.1、测试配置参数

5.1.1、块存储测试配置参数

块存储测试配置参数的定义顺序: HD, SD, WD, RD

  • HD : ( Host Define 主机定义),非必选项,单机运行时不需要配置 HD 参数,一般只有在多主机联机(给多个主机命名,以便在结果中区分)测试时才需要配置;
    • hd : 标识主机定义的名称,多主机运行时,可以使用 hd1、hd2、hd3…区分;
    • system : 主机 IP 地址或主机名;
    • vdbench : vdbench 执行文件存放路径,当多主机存放路径不同时,可在 hd 定义时单独指定;
    • user : master/slave 通信使用的用户名;
    • shell : 在多主机联机测试时, mater/slave 主机间通信方式,可选值为 rsh/ssh/vdbench ,默认值为 rsh 。当参数值为 rsh 时,需要配置 master/slave 主机 rsh 互信,考虑到 rsh 使用明文传输,安全级别不够,通常情况下不建议使用这种通信方式;当参数值为 ssh 时,需要配置 master/slave 主机 ssh 互信,通常 Linux 主机联机时使用此通信方式;当参数值为 vdbench ,需要在所有 slave 主机运行 vdbench rsh 启用 vdbench 本身的 rsh 守护进程,通常 Window 主机联机时使用此通信方式;
  • SD : ( Storage Define 存储定义);
    • sd : 标识存储定义的名称;
    • hd : 标识主机定义的名称;
    • lun : 写入块设备,如 /dev/sdb, /dev/sdc…;
    • openflags : 通过设置为 o_direct ,以无缓冲缓存的方式进行读写操作;
    • threads : 对 SD 的最大并发 I/O 请求数量;
  • WD : ( Workload Define 工作负载定义);
    • wd : 标识工作负载定义的名称;
    • sd : 标识存储定义的名称;
    • seekpct : 随机寻道的百分比,可选值为 0 或 100 (也可使用 sequential 或 random 表示),默认值为 100 。设置为 0 时表示顺序,设置为 100 时表示随机;
    • rdpct : 读取请求占请求总数的百分比,设置为 0 时表示写,设置为 100 时表示读;
    • xfersize : 要传输的数据大小。默认设置为 4k ;
    • skew : 非必选项,一般在多个工作负载时需要指定,表示该工作负载占总工作量百分比( skew 总和为 100 );
  • RD : ( Run Define 运行定义);
    • rd : 标识运行定义的名称;
    • wd : 标识工作负载定义的名称;
    • iorate : 此工作负载的固定 I/O 速率,常用可选值为 100、max 。当参数值为 100 时,以每秒 100 个 I/Os 的速度运行工作负载,当参数值设置为一个低于最大速率的值时,可以达到限制读写速度的效果。当参数值为 max 时,以最大的 I/O 速率运行工作负载,一般测试读写最大性能时,该参数值均 max ;
    • warmup : 预热时间(单位为秒),默认情况下 vdbench 会将第一个时间间隔输出数据排除在外,程序在预热时间内的测试不纳入最终测试结果中(即预热结束后,才开始正式测试)。当 interval = 5 、 elapsed = 600 时,测试性能为 2 到 elapsed / interval ,即 (avg_2 - 120) 时间间隔内的平均性能。当 interval = 5 、warmup = 60 、elapsed = 600 时,测试性能为 1 + (warmup / interval) 到 (warmup + elapsed) / interval,即 (avg_13 - 132) 时间间隔内的平均性能;
    • maxdata : 读写数据大小,通常情况下,当运行 elapsed 时间后测试结束;当同时指定 elapsed 和 maxdata 参数值时,以最快运行完的参数为准(即 maxdata 测试时间小于 elapsed 时,程序写完 elapsed 数据量后结束)。当参数值为 100 以下时,表示读写数据量为总存储定义大小的倍数(如 maxdata = 2 ,2 个存储定义(每个存储定义数据量为 100G ),则实际读写数据大小为 400G )。当参数值为 100 以上时,表示数据量为实际读写数据量(可以使用单位 M、G、T 等);
    • elapsed : 测试运行持续时间(单位为秒),默认值为 30 ;
    • interval : 报告时间间隔(单位为秒);

5.1.2、文件存储测试配置参数

文件存储测试配置参数的定义顺序: HD, FSD, FWD, RD

  • HD : ( Host Define 主机定义),非必选项,单机运行时不需要配置 HD 参数,一般只有在多主机联机(给多个主机命名,以便在结果中区分)测试时才需要配置;
    • hd : 标识主机定义的名称,多主机运行时,可以使用 hd1、hd2、hd3… 区分;
    • system : 主机 IP 地址或主机名;
    • vdbench : vdbench 执行文件存放路径,当多主机存放路径不同时,可在hd定义时单独指定;
    • user : master/slave 通信使用用户;
    • shell : 多主机联机测试时, mater/slave 主机间通信方式。可选值为 rsh/ssh/vdbench,默认值为 rsh 。当参数值为 rsh 时,需要配置 master/slave 主机 rsh 互信,考虑到 rsh 使用明文传输,安全级别不够,通常情况下不建议使用这种通信方式。当参数值为 ssh 时,需要配置 master/slave 主机 ssh 互信,通常 Linux 主机联机时使用此通信方式。当参数值为 vdbench ,需要在所有 slave 主机运行 vdbench rsh 启用 vdbench 本身的 rsh 守护进程,通常 Window 主机联机时使用此通信方式;
  • FSD : ( File System Define 文件系统定义);
    • fsd : 标识文件系统定义的名称,多文件系统时(fsd1、fsd2、fsd3…),可以指定 default (将相同的参数作为所有fsd的默认值);
    • anchor : 文件写入根目录;
    • depth : 创建目录层级数(即目录深度);
    • width : 每层文件夹的子文件夹数;
    • files : 测试文件个数( vdbench 测试过程中会生成多层级目录结构,实际只有最后一层目录会生成测试文件);
    • size : 每个测试文件大小;
    • distribution : 可选值为 bottom/all ,默认为 bottom 。当参数值为 bottom 时,程序只在最后一层目录写入测试文件。当参数值为 all 时,程序在每一层目录都写入测试文件;
    • shared : 可选值为 yes/no ,默认值为 no 。一般只有在多主机联机测试时指定。vdbench 不允许不同的 slave 之间共享同一个目录结构下的所有文件,因为这样会带来很大的开销,但是它们允许共享同一个目录结构。加入设置了shared=yes ,那么不同的 slave 可以平分一个目录下所有的文件来进行访问,相当于每个 slave 有各自等分的访问区域,因此不能测试多个客户的对同一个文件的读写。当多主机联机测试时,写入的根目录 anchor 为同一个路径时,需要指定参数值为 yes ;
  • FWD : ( FileSystem Workload Defile 文件系统工作负载定义);
    • fwd : 标识文件系统工作负载定义的名称,多文件系统工作负载定义时,可以使用 fwd1、fwd2、fwd3… 区分;
    • fsd : 标识此工作负载使用文件存储定义的名称;
    • host : 标识此工作负载使用主机;
    • operation : 文件操作方式,可选值为 read/write ;
    • rdpct : 读操作占比百分比,一般混合读写时需要指定。可选值为 0~100 ,当值为 60 时,则混合读写比为 6:4 ;
    • fileio : 标识文件 I/O 将执行的方式,可选值为 random/sequential ;
    • fileselect : 标识选择文件或目录的方式,可选值为 random/sequential ;
    • xfersize : 数据传输(读取和写入操作)处理的数据大小(即单次 IO 大小);
    • threads : 此工作负载的并发线程数量;
  • RD : ( Run Define 运行定义);
    • rd : 标识文件系统运行定义的名称;
    • fwd : 标识文件系统工作负载定义的名称;
    • fwdrate : 每秒执行的文件系统操作数量。设置为 max,表示不做任何限制,按照最大强度自适应;
    • format : 标识预处理目录和文件结构的方式,可选值为 yes/no/restart 。 yes 表示删除目录和文件结构再重新创建。 no 表示不删除目录和文件结构。 restart 表示只创建未生成的目录或文件,并且增大未达到实际大小的文件;
    • elapsed : 测试运行持续时间(单位为秒),默认值为 30 ;
    • interval : 结果输出打印时间间隔(单位为秒);

5.2、测试命令示例

5.2.1、块存储测试命令示例

**读写测试配置文件:**( 该文件完整路径为 /root/vdbench/conf/block.conf )

hd=default,vdbench=/root/vdbench/,user=root,shell=ssh
hd=hd1,system=node01
hd=hd2,system=node02

sd=sd1,hd=hd1,lun=/dev/rbd01,openflags=o_direct,threads=6
sd=sd2,hd=hd2,lun=/dev/rbd02,openflags=o_direct,threads=6

wd=wd1,sd=sd1,seekpct=100,rdpct=100,xfersize=4m,skew=100
wd=wd2,sd=sd1,seekpct=100,rdpct=50,xfersize=4m,skew=100
wd=wd3,sd=sd1,seekpct=100,rdpct=0,xfersize=4m,skew=100
wd=wd4,sd=sd2,seekpct=100,rdpct=100,xfersize=4m,skew=100
wd=wd5,sd=sd2,seekpct=100,rdpct=50,xfersize=4m,skew=100
wd=wd6,sd=sd2,seekpct=100,rdpct=0,xfersize=4m,skew=100

rd=rd1,wd=wd1,iorate=max,maxdata=50GB,warmup=30,elapsed=100,interval=1
rd=rd2,wd=wd2,iorate=max,maxdata=50GB,warmup=30,elapsed=100,interval=1
rd=rd3,wd=wd3,iorate=max,maxdata=50GB,warmup=30,elapsed=100,interval=1
rd=rd4,wd=wd4,iorate=max,maxdata=50GB,warmup=30,elapsed=100,interval=1
rd=rd5,wd=wd5,iorate=max,maxdata=50GB,warmup=30,elapsed=100,interval=1
rd=rd6,wd=wd6,iorate=max,maxdata=50GB,warmup=30,elapsed=100,interval=1

测试命令:

# 运行5秒的块设备测试,用于测试 vdbench 是否可用
vdbench -t

# 实际测试
vdbench -f /root/vdbench/conf/block.conf

5.2.2、文件存储测试命令示例

**测试配置文件:**( 该文件完整路径为 /root/vdbench/conf/fs.conf )

hd=default,vdbench=/root/vdbench/,user=root,shell=ssh
hd=hd1,system=node01
hd=hd2,system=node02

fsd=default,depth=2,width=10,files=100,size=4m
fsd=fsd1,anchor=/mnt/cephfs/test01
fsd=fsd2,anchor=/mnt/cephfs/test02

fwd=fwd1,fsd=fsd1,host=hd1,operation=write,xfersize=4m,fileio=sequential,fileselect=random,threads=8
fwd=fwd2,fsd=fsd2,host=hd2,operation=write,xfersize=4m,fileio=sequential,fileselect=random,threads=8
fwd=fwd3,fsd=fsd1,host=hd1,operation=read,xfersize=4m,fileio=sequential,fileselect=random,threads=8
fwd=fwd4,fsd=fsd2,host=hd2,operation=read,xfersize=4m,fileio=sequential,fileselect=random,threads=8

rd=rd1,fwd=(fwd1-fwd2),fwdrate=max,format=restart,elapsed=300,warmup=30,interval=1
rd=rd2,fwd=(fwd3-fwd4),fwdrate=max,format=restart,elapsed=300,warmup=30,interval=1

测试命令:

# 运行5秒的文件系统测试,用于测试 vdbench 是否可用
vdbench -tf

# 实际测试
vdbench -f /root/vdbench/conf/fs.conf

5.3、测试结果解析

测试完成后,vdbench 会将输出结果输出到当前目录的 output 目录中,其中 output 中存在如下文件:

  • anchors.html : 目录状态报告;
  • config.html : 脚本 ./linux/config.sh 的输出信息;
  • errorlog.html : 运行时的错误日志。当运行测试启用数据校验时,它可能会包含一些错误信息,比如无效的密钥读取,无效的 lba 读取(一个扇区的逻辑字节地址),无效的 SD/FSD 名称读取,数据损坏,坏扇区等;
  • flatfile.html : vdbench 生成的一种逐列的 ASCII 格式的信息,可以使用 parseflat 参数解析结果,可用于生成图表信息;
  • format.histogram.html :
  • format.html : fwd 的 format 报告;
  • fsd1.histogram.html :
  • fsd1.html : fsd 为 fsd1 的报告;
  • fwd1.histogram.html :
  • fwd1.html : fwd 为 fwd1 的报告;
  • hd1-0.html : Slave=hd1-0 的 slave 摘要报告;
  • hd1-0.stdout.html : slave 的标准输出/标准错误=hd1-0 ;
  • hd1.html : hd1 的主机摘要报告;
  • hd1.var_adm_msgs.html :
  • histogram.html : 一种包含报告柱状图的响应时间、文本格式的文件,总响应时间直方图;
  • logfile.html : 包含 Java 代码写入控制台窗口的每行信息的副本,就是终端上运行 vdbench 输出信息的副本,logfile.html 主要用于调试用途;
  • parmfile.html : 包含测试运行配置参数信息,就是运行时指定的配置文件的副本;
  • parmscan.html : 解析传入的配置参数文件内容的记录日志;
  • skew.html : 工作负载偏差报告,仅在以下情况下才会生成偏差信息:有多个工作负载定义 (WD/FWD)、存在多个存储定义(SD/FSD)、有多个主机、有不止一个奴隶(尽管这些规则有时可能会被忽略);
  • status.html : vdbench 运行的状态信息,主要是展示了不同时刻 vdbench 的状态信息;
  • summary.html : 记录全部数据信息,显示每个报告间隔内总体性能情况及工作负载情况,以及除第一个间隔外的所有间隔的加权平均值,可以查看该文件,然后可以跳转到其他的各文件;
  • swat_mon.bin :
  • swat_mon_total.txt :
  • totals.html : 记录全部数据计算之后的平均值,一般测试结果从该文件取值,除第一个间隔外所有间隔的加权平均值。文件内部一般包含两个部分:第一部分会展示文件存储目录结构及数据填充的平均性能值,其中的 “starting RD=format_for_*” 的条目数据是为了初始化测试环境(创建文件夹,空文件等);第二部分会展示执行测试过程中除第一个时间间隔外所有时间间隔平均性能值(主要看这部分的内容);

六、mdtest

用途:

  • 测试文件存储元数据性能;

环境初始化与安装:

# 安装所需依赖
# centos
yum install -y openmpi
# ubuntu
apt install -y openmpi libopenmpi-dev

# 验证依赖
which mpicc mpic++

# 编译安装
git clone https://github.com/hpc/ior.git
cd ior
./bootstrap
./configure
make
make install

# 验证安装
which mdtest
mdtest -h

6.1、测试配置参数

flag 类参数:

  • -C : 仅创建文件/目录。即无此 Flag 时,mdtest 会将测试时创建的文件/目录删除,有此 Flag 则会保留这些文件/目录;
  • -T : 仅获取文件/目录的状态;
  • -E : 仅读取文件/目录;
  • -r : 仅删除由之前的测试留下的文件或目录。注意使用时要保留之前测试的参数,才能准确删除期望的内容;
  • -D : 对目录进行性能测试(不涉及文件),否则每个目录内会一半是文件一半是目录;
  • -F : 对文件进行性能测试(不涉及目录),否则每个目录内会一半是文件一半是目录;
  • -k : 使用 mknod 创建文件;
  • -L : 文件仅在目录树的叶子层,否则每层目录下都会有文件;
  • -P : 打印速率和时间,默认情况下只打印开始结束时间,以及汇总的速率信息;
  • --print-all-procs : 所有进程都打印其结果的摘要;
  • -R : 随机访问文件(仅用于统计);
  • -S : 共享文件访问(只有文件,没有目录);
  • -c : 集体创建:任务 0 执行所有创建操作;
  • -t : 计时唯一工作目录的开销;
  • -u : 每个任务一个工作目录;
  • -v : 冗长模式(每次使用该选项时增加一级);
  • -X : 验证读取的数据
  • --verify-write : 写入后立即读回数据来验证数据
  • -y : 写入完成后 sync 文件
  • -Y : 在每个阶段后调用 sync 命令(包含在计时中;注意这会导致从你的结点 flush 所有 IO)
  • -Z : 打印时间,而不是速率
  • --allocateBufferOnGPU : 在 GPU 上分配缓冲区
  • --warningAsErrors : 任何警告都会导致错误(即将所有警告都视为错误)
  • --showRankStatistics : 包括每个排名的统计信息

带参数值类参数:

  • -a : I/O 的 API,取值 POSIX 或 DUMMY。
  • -b : 层次目录结构的分支因子,其实就是每个目录中含有子目录或者子文件的目录的数量;默认值为 1 ;
  • -d : 运行测试的目录,可以有多个,用@ 隔开,如 -d=./out1@test/out2@~/out3。默认值为 ./out ;
  • -B : 默认值为 0 ;
  • -e : 从每个文件读取的字节数。默认值为 0 ;
  • -f : 测试将运行的任务的起始编号。默认值为 1 ;
  • -G : 读/写缓冲区中数据的偏移量,如果未设置,则使用随机值。默认值为 -1 ;
  • -i : 测试将运行的迭代次数。默认值为 1 ;
  • -I : 每个目录中的项目数,默认情况下该值控制每个非空目录中的子文件和子目录的数量。默认值为 0 ;
  • -l : 测试将运行的任务的最后编号。默认值为 0 ;
  • -n : 每个进程都会创建/统计/读取/删除 目录和文件。默认值为 0 ;
  • -N : 每个文件/目录操作之间的任务步长(local=0;设置为 1 以避免客户端缓存)。默认值为 0 ;
  • -p : 迭代前延迟(以秒为单位)。默认值为 0 ;
  • --random-seed : -R 的随机数种子。默认值为 0 ;
  • -s : 默认值为 1 ;
  • -V : 详细程度值。与上面 Flag 中的 -v 一样,只是直接设定数字。默认值为 0 ;
  • -w : 创建每个文件后写入每个文件的字节数。默认值为 0 ;
  • -W : 以秒为单位的数字;stonewall 计时器,写入尽可能多的秒数并确保所有进程执行相同数量的操作(目前仅在创建阶段和文件期间停止)。默认值为 0 ;
  • -x : StoneWallingStatusFile,这是一个包含创建阶段迭代次数的文件,可用于在多次运行中拆分阶段。
  • -z : 层次目录结构的深度,即目录的深度,默认值为 0 ;
  • --dataPacketType : 可选值 offset/incompressible/timestamp/random/o/i/t/r ,默认值为 t ;
  • --run-cmd-before-phase :
  • --run-cmd-after-phase :
  • --saveRankPerformanceDetails :

6.2、测试命令示例

# 测试文件相关性能
# 创建3层目录,每层目录中含有10个目录,每个目录中有20个空文件,一共有 10*10*10*20 = 20000 个文件
mdtest -d /mnt/cephfs/test -z 3 -b 10 -I 20 -F -L

# 测试目录相关性能
# 创建3层目录,每层目录中含有10个目录,每个目录中有20个空目录,叶节点中一共有 10*10*10*20 = 20000 个目录
mdtest -d /mnt/cephfs/test -z 3 -b 10 -I 20 -D -L

# 并发测试
# 不允许使用 root 或者 sudo 运行
mpiexec -n 8 mdtest -d /mnt/cephfs/test -z 3 -b 10 -I 20 -u -F -P

七、iozone

用途:

  • 测试文件存储性能;

环境初始化与安装:

# 源码编译安装
wget https://www.iozone.org/src/current/iozone3_506.tar
tar -xvf iozone3_506.tar
cd ./iozone3_506/
cd ./src/current/
make
make linux
ls -al ./
cp iozone /usr/bin/iozone

# 验证安装
which iozone
iozone -v
iozone -h

7.1、测试配置参数

-a   自动模式
-A 自动2模式
-b 文件名,创建 Excel 工作表文件
-B 使用 mmap() 文件
-c 在时间计算中包含关闭操作
-C 在吞吐量测试中显示每个子进程传输的字节数
-d 从屏障中微秒延迟
-D 在 mmap 文件上使用 msync(MS_ASYNC)
-e 在时间计算中包含刷新(fsync, fflush)操作
-E 运行扩展测试
-f 文件名,使用的文件
-F 文件名,吞吐量测试中每个进程/线程的文件
-g 自动模式下设置最大文件大小(以kBytes为单位)(或 m ,或 g)
-G 在 mmap 文件上使用 msync(MS_SYNC)
-h 帮助
-H 使用 POSIX 异步 I/O 进行#次异步操作
-i 要运行的测试
0=write/rewrite, 1=read/re-read, 2=random-read/write
3=Read-backwards, 4=Re-write-record, 5=stride-read, 6=fwrite/re-fwrite
7=fread/Re-fread, 8=random_mix, 9=pwrite/Re-pwrite, 10=pread/Re-pread
11=pwritev/Re-pwritev, 12=preadv/Re-preadv
-I 对所有文件操作使用VxFS VX_DIRECT, O_DIRECT或O_DIRECTIO
-j 设置文件访问的步幅为(# * 记录大小)
-J 每次 I/O 操作前的计算周期毫秒数
-k 使用 POSIX 异步 I/O (无bcopy)进行#次异步操作
-K 为读者创建访问模式抖动
-l 要运行的进程数量下限
-L 将处理器缓存行大小设置为值(以字节为单位)
-m 使用多个缓冲区
-M 报告 uname -a 输出
-n 自动模式下设置最小文件大小(以kBytes为单位)(或 m ,或 g)
-N 以每次操作的微秒数报告结果
-o 写操作是同步的 (O_SYNC)
-O 以每秒操作数给出结果
-p 清除开启
-P 将进程/线程绑定到处理器,从此CPU开始
-q 自动模式下设置最大记录大小(以kBytes为单位)(或 m ,或 g)
-Q 创建偏移/延迟文件
-r 单次操作的大小
或 -r #k .. 以kB为单位的大小
或 -r #m .. 以MB为单位的大小
或 -r #g .. 以GB为单位的大小
-R 生成Excel报告
-s 文件大小
或 -s #k .. 以kB为单位的大小
或 -s #m .. 以MB为单位的大小
或 -s #g .. 以GB为单位的大小
-S 将处理器缓存大小设置为值(以kBytes为单位)
-t 吞吐量测试中使用的线程或进程数量
-T 使用 POSIX 线程进行吞吐量测试
-u 要运行的进程数量上限
-U 在测试之间重新挂载挂载点
-v 版本信息
-V 验证数据模式写/读
-w 不取消链接临时文件
-W 读取或写入时锁定文件
-x 关闭石墙效应
-X 文件名,写入遥测文件。包含(偏移量 记录长度 计算时间)的ascii行
-y 自动模式下设置最小记录大小(以kBytes为单位)(或# m或# g)
-Y 文件名,读取遥测文件。包含(偏移量 记录长度 计算时间)的ascii行
-z 与 -a 结合使用以测试所有可能的记录大小
-Z 启用 mmap I/O 和文件 I/O 的混合
-+b 突发大小(KB),突发之间的睡眠时间(毫秒)
-+E 使用现有的非 iozone 文件进行只读测试
-+F 在 thread_mix_test 中写入前截断文件
-+J 在吞吐量计算中包含思考时间(-j
-+K 索尼特别版。手动控制测试8。
-+m 集群文件名,启用集群测试
-+d 文件 I/O 诊断模式。(用于排除文件 I/O 子系统故障)
-+u 启用 CPU 利用率输出(实验性)
-+x 用于增加文件和记录大小的乘数
-+p 混合中读取的百分比
-+r 启用 O_RSYNC|O_SYNC 进行所有测试。
-+t 启用网络性能测试。需要 -+m
-+n 未选择重新测试。禁用重新定位记录的位置。通常用于防止某些文件系统优化对测试结果的影响,使得测试更加接近真实应用场景。
-+k 使用恒定的聚合数据集大小。
-+q 测试之间的延迟(秒)。
-+l 启用记录锁定模式。
-+L 启用记录锁定模式,使用共享文件。
-+B 顺序混合工作负载。
-+D 启用 O_DSYNC 模式。
-+A 启用 madvise 。
0 = normal, 1=random, 2=sequential
3=dontneed, 4=willneed
-+N 不在顺序写入时截断现有文件。
-+S 可去重数据仅限于在每个数字标识的文件集中共享。
-+W 将此值添加到子线程ID,以便在保持与先前存在的文件的正确去重能力的同时添加其他文件,这些文件在同一种子组中(-+S)。
-+V 启用共享文件。无锁定。
-+X 启用文件系统测试的短路模式。在此模式下,所有结果均无效。
-+Z 启用旧数据集兼容模式。警告.. 已发布的
黑客可能会使这些结果无效,并为结果生成虚假的高值。
-+w 缓冲区中可去重数据的百分比。
-+y 缓冲区中可去重数据在文件内和跨文件的百分比。
-+C 缓冲区中可去重数据在文件内但不跨文件的百分比。
-+a 可压缩数据的百分比。
-+Q 去重粒度大小。
-+H 主机名, PIT 服务器的主机名。
-+P 服务, PIT 服务器的服务。
-+z 启用延迟直方图记录。
-+M 启用去重+压缩选项。(实验性)。
-+R 启用 iozone 从文件中获取文件名。
-+e 启用稀疏而不是在去重区域内和跨去重区域

7.2、测试命令示例

7.2.1、单节点测试命令

测试命令:

# 当前路径下测试读写性能
# 启动 4 个线程,每个线程操作 10g 的文件,每次操作 4m 大小
iozone -i 0 -i 1 -r 4m -s 10g -t 4 -+n

7.2.2、多节点测试命令

测试配置文件: (文件路径为 /etc/iozone/test.conf)

node01 /mnt/cephfs01 /usr/bin/iozone
node01 /mnt/cephfs01 /usr/bin/iozone
node01 /mnt/cephfs01 /usr/bin/iozone
node01 /mnt/cephfs01 /usr/bin/iozone
node01 /mnt/cephfs01 /usr/bin/iozone
node01 /mnt/cephfs01 /usr/bin/iozone
node02 /mnt/cephfs02 /usr/bin/iozone
node02 /mnt/cephfs02 /usr/bin/iozone

测试命令:

# 在指定机器的指定路径下测试读写性能
# 启动 8 个线程,
/usr/bin/iozone -i 0 -i 1 -r 4m -s 10g -t 8 -+n -+m /etc/iozone/test.conf

八、cosbench

用途:

  • 测试对象存储性能;

目前社区已经很长时间没有跟进了。

环境初始化与安装:

# cosbench 依赖 java 和 nc
dnf install java nmap-ncat

# 安装 cosbench ,基于 java 开发
# 这里建议不要使用 0.4.2 正式版,可能会遇到程序无法启动的问题,参考 https://github.com/intel-cloud/cosbench/issues/380
wget https://github.com/intel-cloud/cosbench/releases/download/v0.4.2.c4/0.4.2.c4.zip
unzip 0.4.2.c4.zip
cd 0.4.2.c4
chmod +x ./*.sh

# 如果机器为 centos ,在执行下面的脚本时可能会遇到下面的错误:
# Ncat: Invalid -i timeout "0" (must be greater than 0 and less than 2147483s). QUITTING.
# 解决办法参见: https://github.com/intel-cloud/cosbench/issues/240
# 需要修改 cosbench-start.sh 文件中的 TOOL_PARAMS="-i 0" => TOOL_PARAMS=""

# 启动 Driver , 默认监听端口为 18088
./start-driver.sh

# 启动 Controller , 默认监听端口为 19088
./start-controller.sh

# 使用浏览器访问,注意访问路径需要添加上 /controller/ ,否则无法访问
http://$IPADDR:19088/controller/

# 修改 Driver 配置, 修改 name 和 url 信息
# 位于 conf/driver.conf 或者 conf/driver_template.conf
# cat conf/driver_template.conf
cat conf/driver.conf

# 修改 Controller 配置, 修改 driver 数量,日志级别, driver name 和 driver ip 等信息
# 位于 conf/controller.conf
cat conf/controller.conf

8.1、测试配置参数

测试任务的配置文件位于 conf 目录中,这里解释 s3-config-sample.xml 文件。

配置详情:

<?xml version="1.0" encoding="UTF-8" ?>
<workload name="s3-sample" description="sample benchmark for s3">
<storage type="s3" config="accesskey=<accesskey>;secretkey=<scretkey>;proxyhost=<proxyhost>;proxyport=<proxyport>;endpoint=<endpoint>" />
<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>

字段解释:

  • workload : 测试任务详情。 name 为任务名称。description 为任务描述信息。
  • storage : 存储详情。 type 为存储类型,这里为 s3 。 config 为存储类型对应的配置(endpoint 格式为 host:port)。 默认的 config 配置模板中并没有给出 path_style_access 参数,在使用 ceph rgw 的时候需要将该值设置为 true ,否则会出现 auth 错误。
  • workflow : 工作流详情。
  • workstage : 工作流阶段。 name 为工作流阶段名称。
  • work : 具体工作详情, type 对应 workstage name 。 workers 表示执行该阶段的时候开启多少个工作线程。 runtime 表示运行的时间,时间默认为秒。
    • init : 初始化阶段,主要是进行 bucket 的创建。 cprefix 为 bucket 的名称前缀, containers 表示 bucket 的拼接的后缀。
    • prepare : 配置为 bucket 写入的数据, workers 和 部分 config 含义与 init 阶段相同,除此之外还需要配置 objects ,表示一轮写入多少个对象,以及 object 的大小。
    • main : 进行测试的阶段。
    • cleanup : 进行环境的清理,主要是删除 bucket 中的数据,保证测试后的数据不会保留在集群中。
    • dispose : 删除 bucket 。
  • operation : 操作详情。 type 为操作类型,可选值为 read/write/delete 等。 ratio 表示该操作所占有操作的比例。 config 配置 bucket 的前缀后缀等信息。

8.2、测试命令示例

示例配置:

<?xml version="1.0" encoding="UTF-8" ?>
<workload name="ceph-rgw-bench" description="ceph rgw bench">
<storage type="s3" config="accesskey=8JCZSOON4U9AI90CSSTQ;secretkey=b6CzA1fXvG0auCBd3irVjHAZD3URtSrPAh40F2nB;endpoint=http://$ADDR:$PORT;path_style_access=true" />
<workflow>
<workstage name="init">
<work type="init" workers="1" config="cprefix=cephs3cosbench;containers=r(1,2)" />
</workstage>
<workstage name="prepare">
<work type="prepare" workers="1" config="cprefix=cephs3cosbench;containers=r(1,2);objects=r(1,10);sizes=c(64)KB" />
</workstage>
<workstage name="main">
<work name="main" workers="4" runtime="30">
<operation type="read" ratio="80" config="cprefix=cephs3cosbench;containers=u(1,2);objects=u(1,10)" />
<operation type="write" ratio="20" config="cprefix=cephs3cosbench;containers=u(1,2);objects=u(11,20);sizes=c(64)KB" />
</work>
</workstage>
<workstage name="cleanup">
<work type="cleanup" workers="1" config="cprefix=cephs3cosbench;containers=r(1,2);objects=r(1,20)" />
</workstage>
<workstage name="dispose">
<work type="dispose" workers="1" config="cprefix=cephs3cosbench;containers=r(1,2)" />
</workstage>
</workflow>
</workload>

相关命令:

# 提交任务执行
./cli.sh submit conf/cephrgw.xml

九、cbt

十、相关资料