背景

最近公司的一台实例类型为m5.2xlarge(8个vCPU,32G的Memory)的机器磁盘性能不行,于是需要做个磁盘性能测试。这里使用fio测试工具。


1.AWS磁盘类型简介

AWS EC2 instance 目前EBS有5种类型,分别是gp2,io1,st1,sc1,standard. 笔者只介绍standard,其他四种可自行上网了解。

standard是AWS上一代的volumn HDD类型,卷大小1G-1T,最大IOPS 40-200,最大吞吐量40-90M/s;


Previous Generation Volumes
Volume TypeEBS Magnetic
DescriptionPrevious generation HDD
Use CasesWorkloads where data is infrequently accessed
API Namestandard
Volume Size1 GiB-1 TiB
Max. IOPS/Volume40–200
Max. Throughput/Volume40–90 MiB/s
Max. IOPS/Instance80,000
Max. Throughput/Instance1,750 MiB/s
Dominant Performance AttributeIOPS


2.fio工具简介,安装

(1)fio是专门用来测试磁盘性能的一种好用工具,有顺序读,顺序写,顺序读写,随机读,随机写,随机读写等模式,本篇只测试顺序读和随机读,不测试写。

安装fio非常简单,直接使用yum install -y fio即可。


注意

使用fio测试写的时候,会损害磁盘上已经存在的数据,严重的话会导致系统奔溃,起不来。

(不要问我为什么知道,因为这是血和泪的教训,笔者曾把一台已有数据的EC2实例磁盘测试死掉,包括根磁盘和数据盘两块盘,最后怎么都起不来,辛亏有AMI可以恢复。)


(2)常用参数介绍

filename=/dev/sdb1       指定测试的文件设备

directory 存储文件的目录

direct=1                 测试过程绕过机器自带的buffer,使测试结果更真实。

bs=16k                   单次io的块文件大小为16k

size=2g                  指定测试文件大小为2g,不指定这个参数,默认是当前磁盘的全部大小

numjobs=30               指定测试线程为30.

runtime=1000 测试时间为1000秒

time_based=1              : Keep running until runtime/timeout is met

ioengine=psync           io引擎使用pync方式

rw=randwrite             测试随机写的I/O

name  指定这次job的名称

iodepth : Number of IO buffers to keep in flight

randrepeat            : Use repeatable random IO pattern

--output=test.sql  将结果输出到指定文件中

allow_mounted_write=1 允许写入测试

rwmixread               : Percentage of mixed workload that is reads

rwmixwrite              : Percentage of mixed workload that is writes


rw值:

read 顺序读

write 顺序写

randread 随机读

randwrite 随机写

rw或readwrite 顺序混合读写

randrw 随机混合读写


3.测试脚本

为了便于测试和收集结果,笔者写了个简单的测试脚本如下:

#!/bin/bash

. ~/.bash_profile
set -u
set -x
set -e
BASEDIR=/usr/local/fio
cd $BASEDIR
exec 3>&1 4>&2 1>> fio.log 2>&1

FILENAME=/dev/nvme2n1p1
DIRECT=1
#RW=read
RWS="read randread"
RANDREPEAT=0
IOENGINE=libaio
BSS="8 16 32 64 128 256 1024"
IODEPTH=8
TIME_BASED=1
RUNTIME=180
NAME=read
for rw in `echo "${RWS}"`
do
  for bs in `echo "${BSS}"`
  do
  /bin/fio --filename=${FILENAME} --direct=${DIRECT} --rw=${rw} --randrepeat=${RANDREPEAT} --ioengine=${IOENGINE} --bs=${bs}k --iodepth=${IODEPTH} --time_based=${TIME_BASED} --runtime=${RUNTIME} --name=${NAME} --output=${rw}_${bs}.txt
  sleep 3
  done
done


4.测试结果整理分析


bs(K)Read_IOPSRead_BW(MIB/s)Randread_IOPSRandread_BW(MIB/s)
8159312.4168713.2
1696615.195514.9
3295629.991528.6
649115698161.4
12874693.378698.3
256686172711178
1024242243246246


(1)顺序读和随机读的IOPS对比图

blob.png


(2)顺序读和随机读的吞吐量对比图

blob.png

5.结论

(本结论仅针对本次实验结果,因为测试样本不足可能导致测试结果不准)

(1)吞吐量=IOPS*bs/1024

(2)顺序读和顺序写IOPS和吞吐量差距不大。

(3)磁盘的吞吐量存在瓶颈250MIB/s,如果需要更高性能的BW,可以考虑使用AWS推荐的gp2。


参考链接

Amazon EBS Volume Types

Benchmark EBS Volumes