背景

最近公司的一台实例类型为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 Type EBS Magnetic
Description Previous generation HDD
Use Cases Workloads where data is infrequently accessed
API Name standard
Volume Size 1 GiB-1 TiB
Max. IOPS/Volume 40–200
Max. Throughput/Volume 40–90 MiB/s
Max. IOPS/Instance 80,000
Max. Throughput/Instance 1,750 MiB/s
Dominant Performance Attribute IOPS


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_IOPS Read_BW(MIB/s) Randread_IOPS Randread_BW(MIB/s)
8 1593 12.4 1687 13.2
16 966 15.1 955 14.9
32 956 29.9 915 28.6
64 911 56 981 61.4
128 746 93.3 786 98.3
256 686 172 711 178
1024 242 243 246 246


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


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

5.结论

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

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

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

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


参考链接

Amazon EBS Volume Types

Benchmark EBS Volumes