本文中含有需要您注意的重要提示信息,忽略该信息可能对您的业务造成影响,请务必仔细阅读。
阿里云ESSD云盘结合25GE网络和RDMA技术,为您提供单盘高达100万的随机读写能力和单路低时延性能。您可以按照本示例配置ESSD云盘性能的压测条件,测试ESSD云盘作为裸盘时的IOPS。
压测条件
测试工具:使用FIO。
说明FIO(Flexible I/O Tester)是一个开源的、强大的I/O性能测试工具,可以用来对存储设备进行随机读写、顺序读写等负载测试。
实例规格:推荐使用ecs.g7se.32xlarge。更多信息,请参见通用型(g系列)。
镜像:使用公共镜像中高版本的Linux镜像,本文使用Alibaba Cloud Linux 3。
说明经测试发现部分Linux发行版镜像可能无法达到预期的性能,强烈推荐您使用阿里云官方维护的Alibaba Cloud Linux 3镜像。
ESSD云盘:
测试裸盘可以获得较为真实的云盘性能,建议您直接通过FIO压测裸盘进行云盘性能测试。
推荐使用ESSD PL3云盘。关于ESSD云盘的更多信息,请参见ESSD云盘。
重要测试裸盘可以获得较为真实的块存储性能。但如果块存储设备中含有分区、文件系统以及其他数据,直接使用FIO压测会导致文件系统异常以及数据丢失,请在测试前提前创建快照做好数据备份。具体操作,请参见创建快照。
强烈建议您不要将操作系统所在的系统盘或含有数据的数据盘作为测试对象,以避免数据丢失。建议在新创建的空数据盘上使用工具测试块存储性能。
性能测试结果均在测试环境下获得,仅供参考。在真实生产环境中,受网络环境、并发访问量等因素影响,云盘的性能表现可能存在差异,请您以实际情况为准。
操作步骤
远程连接ECS实例。
具体操作,请参见使用Workbench工具以SSH协议登录Linux实例。
运行以下命令,查询块存储的设备名称。
sudo fdisk -lu
如上图所示,表示该实例有3块块存储设备,系统盘/dev/vda、数据盘/dev/vdb、/dev/vdc。
运行以下命令,查询块存储设备是否存在分区和文件系统。
sudo blkid
如上图所示,块存储设备/dev/vda与/dev/vdb上存在分区及文件系统,而结果中未存在/dev/vdc相关的回执信息,表明/dev/vdc没有分区及文件系统。
在测试块存储性能前,请确保已经对测试对象进行数据备份,避免数据丢失。具体操作,请参见创建快照。
说明使用快照会产生计费,更多信息,请参见快照计费。
运行以下命令,安装libaio库和测试工具FIO。 示例如下,请根据不同的系统选择指令。
Alibaba Cloud Linux 2/3版本、CentOS 6及以上版本
重要由于CentOS 6和CentOS 8结束生命周期(EOL),所以如果您使用的是CentOS 6或者CentOS 8系统的ECS实例,请先切换源地址。具体操作,请参见CentOS 6 EOL如何切换源?和CentOS 8 EOL如何切换源?。
sudo yum install libaio libaio-devel fio -y
Debian 9及以上版本、Ubuntu14及以上版本
重要由于Debain9和Debain10结束生命周期(EOL),所以如果您使用的是Debain9和Debain10系统的ECS实例,请先切换源地址。具体操作,请参见Debian 9/10 EOL如何切换源?。
sudo apt-get update sudo apt-get install libaio* fio -y
运行以下命令,切换路径。
cd /tmp
运行以下命令,新建test100w.sh脚本。
sudo vim test100w.sh
在test100w.sh中粘贴以下内容。
关于脚本内容的详细说明,请参见test100w.sh脚本解读。
#!/bin/bash DEV_NODE=your_device DEV_NAME=/dev/$DEV_NODE function CheckHasFS { local device=$1 # 设备路径 # 检查设备是否存在 if [ ! -b "$device" ]; then echo "错误: 设备 $device 不存在" exit 1 fi # 使用 `blkid` 命令检查分区表和文件系统类型 local pt_type=$(sudo blkid -o value -s PTTYPE "$device") local fs_type=$(sudo blkid -o value -s TYPE "$device") if [ -n "$pt_type" ] || [ -n "$fs_type" ]; then return 1 else return 0 fi } CheckHasFS "$DEV_NAME" if [ $? -eq 1 ]; then echo "$DEV_NAME 包含分区表或文件系统,停止 fio 脚本!" exit 1 fi function RunFio { numjobs=$1 # 实例中的测试线程数,例如示例中的10 iodepth=$2 # 同时发出I/O数的上限,例如示例中的64 bs=$3 # 单次I/O的块文件大小,例如示例中的4k rw=$4 # 测试时的读写策略,例如示例中的randwrite size=$5 filename=$6 # 指定测试文件的名称,例如示例中的/dev/your_device nr_cpus=`cat /proc/cpuinfo |grep "processor" |wc -l` if [ $nr_cpus -lt $numjobs ];then echo “Numjobs is more than cpu cores, exit!” exit -1 fi let nu=$numjobs+1 cpulist="" for ((i=1;i<10;i++)) do list=`cat /sys/block/$DEV_NODE/mq/*/cpu_list | awk '{if(i<=NF) print $i;}' i="$i" | tr -d ',' | tr '\n' ','` if [ -z $list ];then break fi cpulist=${cpulist}${list} done spincpu=`echo $cpulist | cut -d ',' -f 2-${nu}` echo $spincpu fio --ioengine=libaio --runtime=30s --numjobs=${numjobs} --iodepth=${iodepth} --bs=${bs} --size=${size} --rw=${rw} --filename=${filename} --time_based=1 --direct=1 --name=test --group_reporting --cpus_allowed=$spincpu --cpus_allowed_policy=split } echo 2 > /sys/block/$DEV_NODE/queue/rq_affinity sleep 5 RunFio 10 128 4k randwrite 1024g $DEV_NAME
因测试环境而异,根据实际情况修改test100w.sh脚本。
请将所有
your_device
设置为ESSD云盘实际的设备名,例如nvme1n1。根据实际情况设置
RunFio 10 64 4k randwrite /dev/your_device
中的10(numjobs)、64(iodepth)、4k(bs)、randwrite(rw)和/dev/your_device。numjobs的设置值不能超过cpu cores,您可以使用以下指令查看当前的cpu核心数。
cat /proc/cpuinfo |grep "processor" |wc -l
运行以下命令,测试ESSD云盘性能。
sudo sh test100w.sh
您可以在返回结果中查看
IOPS=***
内容,表示ESSD云盘的IOPS。如果返回结果为如下示例所示,表示当前测试对象存在分区或文件系统,为保证数据安全,fio脚本停止执行,建议您使用新创建的空数据盘进行测试。
[[ecs-user@ecs tmp]$ sudo sh test100w.sh /dev/vdb 包含分区表或文件系统,停止 fio 脚本!
test100w.sh脚本解读
以下命令将块设备的系统参数
rq_affinity
取值修改为2。echo 2 > /sys/block/your_device/queue/rq_affinity
rq_affinity取值
取值说明
1
表示块设备收到I/O完成(I/O Completion)的事件时,这个I/O被发送回处理这个I/O下发流程的vCPU所在Group上处理。在多线程并发的情况下,I/O Completion就可能集中在某一个vCPU上执行,造成瓶颈,导致性能无法提升。
2
表示块设备收到I/O Completion的事件时,这个I/O会在当初下发的vCPU上执行。在多线程并发的情况下,就可以充分发挥各个vCPU的性能。
以下命令分别将几个
jobs
绑定到不同的CPU Core上。fio -ioengine=libaio -runtime=30s -numjobs=${numjobs} -iodepth=${iodepth} -bs=${bs} -rw=${rw} -filename=${filename} -time_based=1 -direct=1 -name=test -group_reporting -cpus_allowed=$spincpu -cpus_allowed_policy=split
说明普通模式下,一个设备(Device)只有一个请求队列(Request-Queue),在多线程并发处理I/O的情况下,这个唯一的Request-Queue就是一个性能瓶颈点。多队列(Multi-Queue)模式下,一个设备(Device)可以拥有多个处理I/O的Request-Queue,充分发挥后端存储的性能。假设您有4个I/O线程,您需要将4个I/O线程分别绑定在不同的Request-Queue对应的CPU Core上,这样就可以充分利用Multi-Queue提升性能。
参数
说明
取值示例
numjobs
I/O线程。
10
/dev/your_device
ESSD云盘设备名。
/dev/nvme1n1
cpus_allowed_policy
FIO提供了参数
cpus_allowed_policy
以及cpus_allowed
来绑定vCPU。split
以上命令一共运行了几个
jobs
,分别绑定在几个CPU Core上,分别对应着不同的Queue_Id。关于如何查看Queue_Id绑定的cpu_core_id,您可以运行如下命令:运行
ls /sys/block/your_device/mq/
。其中,your_device
是您的设备名,例如nvme1n1。运行该命令查看设备名为vd*云盘的Queue_Id。运行
cat /sys/block/your_device/mq/cpu_list
。其中,your_device
是您的设备名,例如nvme1n1。运行该命令查看对应设备名为vd*云盘的Queue*绑定到的cpu_core_id。