缘由:

近日完成了RDS for PostgreSQL到Aurora PostgreSQL的迁移,并且在迁移完成后将数据库版本由10.16升级到了11.11,支持了Graviton 2系列的数据库实例。

想起了上半年AWS有一系列Graviton 2实例热身的宣传活动,有一些文章也指出在RDS上,Graviton 2不仅仅在价格上降低了,更是在性能上有非常明显的提升。所以我速度以r6g拉起一个Aurora Reader,主动做了FO让r6g实例做为Writer开始对外服务。

经过一天的生产环境工作负载的洗礼,表现倒是有点出乎意料,Graviton 2并没有性能上的提升,反而有肉眼可见(但是并不大的)的下降,为了解开困惑并将它量化,我又找到了当时吕琳老师的文章,重新拜读了下,试图重现文中结果。

原文为 重装上阵——Graviton2提升Aurora性价比


本次测试主要采用亚马逊云科技宁夏区域的两个可用区A和C(当然你的A不一定是我的A),每个可用区都会部署一台客户端,配置为c5.2xlarge,上面会安装sysbench,同时在每个可用区都会部署两个Aurora MySQL集群,集群实例使用r5和r6g来做对比,两个类型均采用db.2xlarge规格,8 vCPU以及64GB内存。

客户端只会连接本可用区的数据库实例,这样能确保延迟最小化,同时为了消除随机性,同样的r5的数据库集群也用来做对照。

需要注意的是,吕琳老师原文中Aurora MySQL版本为2.09.1,目前无论是Global还是中国区,提供r6g实例支持的Aurora MySQL最低版本均为2.10.0,所以本文选择2.10.0做为数据库引擎的版本,同时sysbench我们为了简单,直接采用二进制包安装,sysbench版本为1.0.20,也与文中自编译的1.0.18不同,故测试数据有差异是正常的情况。

1) 创建客户端实例

我们按照文中对实例的预置,我们可以构建以下userdata

#!/bin/bash
yum update -y
yum install htop -y
curl -s https://packagecloud.io/install/repositories/akopytov/sysbench/script.rpm.sh | bash
yum -y install sysbench
echo '* soft nofile 65536
* hard nofile 65536
* soft nproc 65536
* hard nproc 65536' | tee /etc/security/limits.d/90-common.conf
sh -c 'for x in /sys/class/net/eth0/queues/rx-*; do echo ff> $x/rps_cpus; done'
sh -c "echo 32768 > /proc/sys/net/core/rps_sock_flow_entries"
sh -c "echo 4096 > /sys/class/net/eth0/queues/rx-0/rps_flow_cnt"
sh -c "echo 4096 > /sys/class/net/eth0/queues/rx-1/rps_flow_cnt"

然后我们就执行以下命令来创建实例,命令会输出实例的ID,注意我们需要创建两个实例,分别在两个子网(两个不同的可用区)

aws ec2 run-instances --image-id ami-010f676abe7d44960 --count 1 --instance-type c5.2xlarge \
  --key-name "Sean's KP" --subnet-id subnet-a82e99c1 --security-group-ids sg-0b3074dcd73519ec6 \
  --user-data file://userdata.txt --tag-specifications 'ResourceType=instance,Tags=[{Key=AZ,Value=cn-northwest-1a}]' \
  --query 'Instances[*].InstanceId' --output text

我们可以通过实例ID来拿到实例的公网IP

$ aws ec2 describe-instances --instance-ids i-089fe48fa8e249215 --query 'Reservations[*].Instances[*].PublicIpAddress' --output text
161.189.163.103 # cn-northwest-1a

$ aws ec2 describe-instances --instance-ids i-0f7ea8e19fc2a128d --query 'Reservations[*].Instances[*].PublicIpAddress' --output text
69.231.130.225 # cn-northwest-1c

等待片刻,实例就准备好了。

我们可以登录上去确认一下,可见sysbench版本。

$ ssh ec2-user@161.189.163.103
The authenticity of host '161.189.163.103 (161.189.163.103)' can't be established.
ECDSA key fingerprint is SHA256:+0L/08T/kQgFCROuSzP/18zUavnI3KvoDyqeXK9k0Ro.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '161.189.163.103' (ECDSA) to the list of known hosts.

       __|  __|_  )
       _|  (     /   Amazon Linux 2 AMI
      ___|\___|___|

https://aws.amazon.com/amazon-linux-2/
[ec2-user@ip-172-31-12-56 ~]$ sysbench --version
sysbench 1.0.20

2) 创建数据库集群及实例

我们需要在两个可用区创建总计4个实例,这个创建过程其实基本上与我之前写的迁移的文章一致,即先要创建Aurora集群,然后再为集群添加主实例。集群参数组为按照文中修改的max_prepared_stmt_count至1048576

aws rds create-db-cluster --db-cluster-identifier aurora-r5-a \
  --database-name sysbench \
  --db-cluster-parameter-group-name aurora-mysql57-tuned \
  --engine aurora-mysql --engine-version 5.7.mysql_aurora.2.10.0 \
  --master-username aurora --master-user-password secret99 \
  --db-subnet-group-name default --vpc-security-group-ids sg-ca6432a2

然后我们为集群添加实例,注意实例的可用区及类型

$ aws rds create-db-instance --db-instance-identifier aurora-r5-a \
  --db-cluster-identifier aurora-r5-a --engine aurora-mysql --db-instance-class db.r5.2xlarge \
  --availability-zone cn-northwest-1a --enable-performance-insights
$ aws rds create-db-instance --db-instance-identifier aurora-r6g-c \
  --db-cluster-identifier aurora-r6g-c --engine aurora-mysql --db-instance-class db.r6g.2xlarge \
  --availability-zone cn-northwest-1c --enable-performance-insights

我们可以拿到4个Aurora MySQL集群。

3) 测试

为了节约时间,我们交叉进行命令的执行(客户端同时发起对不同类型的数据库实例的请求),我们也根据原文中的结果,只取了三种测试中,差异最大的那一组参数来做对比。同时,根据输出的结果,确认调整测试时间至每轮10分钟是不影响结论的。

3.1) 只读测试

分开准备数据,命令如下,四组只有参数不同,其他均相同,故此处以两组示意

sysbench --db-driver=mysql --mysql-host=aurora-r6g-a.cluster-xxxxxx.rds.cn-northwest-1.amazonaws.com.cn \
  --mysql-port=3306 --mysql-user=aurora --mysql-password=secret99 --mysql-db=sysbench \
  --table_size=25000 --tables=250 --events=0 --time=600 oltp_read_only prepare

sysbench --db-driver=mysql --mysql-host=aurora-r5-c.cluster-xxxxxx.rds.cn-northwest-1.amazonaws.com.cn \
  --mysql-port=3306 --mysql-user=aurora --mysql-password=secret99 --mysql-db=sysbench \
  --table_size=25000 --tables=250 --events=0 --time=600 oltp_read_only prepare

文中32只读并发时,获得r6g的性能是r5的137%,故我们以这个参数,进行测试

sysbench --db-driver=mysql --mysql-host=aurora-r6g-a.cluster-xxxxxx.rds.cn-northwest-1.amazonaws.com.cn \
  --mysql-user=aurora --mysql-password=secret99 --mysql-port=3306 --mysql-db=sysbench \
  --table_size=25000 --tables=250 --events=0 --max-time=600 \
  --threads=32 --percentile=95 --range_selects=0 --skip-trx=1 --report-interval=20 oltp_read_only run >> r6g-a_read.log

sysbench --db-driver=mysql --mysql-host=aurora-r5-c.cluster-xxxxxx.rds.cn-northwest-1.amazonaws.com.cn \
  --mysql-user=aurora --mysql-password=secret99 --mysql-port=3306 --mysql-db=sysbench \
  --table_size=25000 --tables=250 --events=0 --max-time=600 \
  --threads=32 --percentile=95 --range_selects=0 --skip-trx=1 --report-interval=20 oltp_read_only run >> r5-c_read.log

可以获得下图这样的输出结果,四个数据库集群(实例),总计有4份报告。

使用以下命令清理数据

sysbench --db-driver=mysql --mysql-host=aurora-r6g-a.cluster-xxxxxx.rds.cn-northwest-1.amazonaws.com.cn \
  --mysql-port=3306 --mysql-user=aurora --mysql-password=secret99 --mysql-db=sysbench \
  --table_size=25000 --tables=250 --events=0 --time=600 oltp_read_only cleanup

sysbench --db-driver=mysql --mysql-host=aurora-r5-c.cluster-xxxxxx.rds.cn-northwest-1.amazonaws.com.cn \
  --mysql-port=3306 --mysql-user=aurora --mysql-password=secret99 --mysql-db=sysbench \
  --table_size=25000 --tables=250 --events=0 --time=600 oltp_read_only cleanup

我们整理一下数据,形成以下表格

可用区 32并发 A 32并发 C
r6g QPS 190953.01 186581.25
r5 QPS 206528.44 190543.50
QPS r6g/r5 92.46% 97.92%
r6g Response Time 2.66 2.18
r5 Response Time 1.86 2.11

可见任何维度上,r6g均要弱于r5。

3.2) 只写测试

准备数据,命令与只读测试雷同

sysbench --db-driver=mysql --mysql-host=aurora-r6g-a.cluster-xxxxxx.rds.cn-northwest-1.amazonaws.com.cn \
  --mysql-port=3306 --mysql-user=aurora --mysql-password=secret99 --mysql-db=sysbench \
  --table_size=25000 --tables=250 --events=0 --time=600 oltp_write_only prepare

sysbench --db-driver=mysql --mysql-host=aurora-r5-c.cluster-xxxxxx.rds.cn-northwest-1.amazonaws.com.cn \
  --mysql-port=3306 --mysql-user=aurora --mysql-password=secret99 --mysql-db=sysbench \
  --table_size=25000 --tables=250 --events=0 --time=600 oltp_write_only prepare

文中,64并发时性能差异最大,可到221%,故我们此处测试64并发时的性能表现

sysbench --db-driver=mysql --mysql-host=aurora-r6g-a.cluster-xxxxxx.rds.cn-northwest-1.amazonaws.com.cn \
  --mysql-user=aurora --mysql-password=secret99 --mysql-port=3306 --mysql-db=sysbench \
  --table_size=25000 --tables=250 --events=0 --max-time=600 \
  --threads=64 --percentile=95 --report-interval=20 oltp_write_only run >> r6g-a_write.log

sysbench --db-driver=mysql --mysql-host=aurora-r5-c.cluster-xxxxxx.rds.cn-northwest-1.amazonaws.com.cn \
  --mysql-user=aurora --mysql-password=secret99 --mysql-port=3306 --mysql-db=sysbench \
  --table_size=25000 --tables=250 --events=0 --max-time=600 \
  --threads=64 --percentile=95 --report-interval=20 oltp_write_only run >> r5-c_write.log

使用以下命令清理数据

sysbench --db-driver=mysql --mysql-host=aurora-r6g-a.cluster-xxxxxx.rds.cn-northwest-1.amazonaws.com.cn \
  --mysql-port=3306 --mysql-user=aurora --mysql-password=secret99 --mysql-db=sysbench \
  --table_size=25000 --tables=250 --events=0 --time=600 oltp_write_only cleanup

sysbench --db-driver=mysql --mysql-host=aurora-r5-c.cluster-xxxxxx.rds.cn-northwest-1.amazonaws.com.cn \
  --mysql-port=3306 --mysql-user=aurora --mysql-password=secret99 --mysql-db=sysbench \
  --table_size=25000 --tables=250 --events=0 --time=600 oltp_write_only cleanup

我们整理一下数据,形成以下表格和图表

可用区 64并发 A 64并发 C
r6g TPS 5405.20 5664.49
r5 TPS 6050.47 5671.28
TPS r6g/r5 89.34% 99.88%
r6g Response Time 16.12 15.55
r5 Response Time 13.70 14.21

一样的,任何维度下,r6g均要弱于r5。

3.3) 读写混合测试

准备数据

sysbench --db-driver=mysql --mysql-host=aurora-r6g-a.cluster-xxxxxx.rds.cn-northwest-1.amazonaws.com.cn \
  --mysql-port=3306 --mysql-user=aurora --mysql-password=secret99 --mysql-db=sysbench \
  --table_size=25000 --tables=250 --events=0 --time=600 oltp_read_write  prepare

sysbench --db-driver=mysql --mysql-host=aurora-r5-c.cluster-xxxxxx.rds.cn-northwest-1.amazonaws.com.cn \
  --mysql-port=3306 --mysql-user=aurora --mysql-password=secret99 --mysql-db=sysbench \
  --table_size=25000 --tables=250 --events=0 --time=600 oltp_read_write  prepare

文中,64并发时性能差异最大,可到160%,故我们此处测试64并发时的性能表现

sysbench --db-driver=mysql --mysql-host=aurora-r6g-a.cluster-xxxxxx.rds.cn-northwest-1.amazonaws.com.cn \
  --mysql-user=aurora --mysql-password=secret99 --mysql-port=3306 --mysql-db=sysbench \
  --table_size=25000 --tables=250 --events=0 --max-time=600 \
  --threads=64 --percentile=95 --report-interval=20 oltp_read_write run >> r6g-a_rw.log

sysbench --db-driver=mysql --mysql-host=aurora-r5-c.cluster-xxxxxx.rds.cn-northwest-1.amazonaws.com.cn \
  --mysql-user=aurora --mysql-password=secret99 --mysql-port=3306 --mysql-db=sysbench \
  --table_size=25000 --tables=250 --events=0 --max-time=600 \
  --threads=64 --percentile=95 --report-interval=20 oltp_read_write run >> r5-c_rw.log

使用以下命令清理数据

sysbench --db-driver=mysql --mysql-host=aurora-r6g-a.cluster-xxxxxx.rds.cn-northwest-1.amazonaws.com.cn \
  --mysql-port=3306 --mysql-user=aurora --mysql-password=secret99 --mysql-db=sysbench \
  --table_size=25000 --tables=250 --events=0 --time=600 oltp_read_write cleanup

sysbench --db-driver=mysql --mysql-host=aurora-r5-c.cluster-xxxxxx.rds.cn-northwest-1.amazonaws.com.cn \
  --mysql-port=3306 --mysql-user=aurora --mysql-password=secret99 --mysql-db=sysbench \
  --table_size=25000 --tables=250 --events=0 --time=600 oltp_read_write cleanup

我们整理一下数据,形成以下表格和图表

可用区 64并发 A 64并发 C
r6g TPS 2505.84 2570.45
r5 TPS 2621.57 2441.87
TPS r6g/r5 95.57% 105.3%
r6g QPS 50128.28 51421.21
r5 QPS 52442.01 48846.77
QPS r6g/r5 95.59% 105.3%
r6g Response Time 34.95 33.12
r5 Response Time 28.67 30.26

可用区A和C表现不一致,偏差范围最大10%。

总结

通过重复三组测试,得到了和原文截然不同的结果,着实出乎了我的意料。性价比是Graviton 2的卖点,通过对比r5.2xlarge和r6g.2xlarge的价格

实例类型 单价
r5.2x 9.58
r6g.2x 8.872
r6g/r5 92.61%

结合性能测试的结果,如果你对性能边界不那么敏感的话,那么r6g依然是比较好的选择。倘若你是为了性能提升选择r6g的话,那么目前性能的表现可能还无法满足你的需要。

注:原始数据可以通过以下链接获得,

Aurora MySQL Graviton2 Benchmark