1. Aurora failover介绍
Amazon Aurora 是亚马逊云科技自研的一项关系数据库服务,它在提供和开源数据库MySQL、PostgreSQL的完好兼容性同时,也能够提供和商业数据库媲美的性能和可用性。性能方面,Aurora MySQL能够支持到与开源标准MySQL同等配置下五倍的吞吐量,Aurora PostgreSQL能够支持与开源标准PostgreSQL同等配置下三倍的吞吐量的提升。在扩展性的角度,Aurora在存储与计算、横向与纵向方面都进行了功能的增强和创新。
Aurora支持多达128TB的存储容量,而且支持10GB为单位的存储层动态收缩。计算方面,Aurora提供多个读副本的可扩展性配置支持一个区域内多达15个读副本的扩展,提供多主的架构来支持同一个区域内4个写节点的扩展,提供Serverless无服务器化的架构实例级别的秒级纵向扩展,提供全球数据库来实现数据库的低延迟跨区域扩展。
如下图所示Aurora Primary Instance与Read Replica使用相同的底层存储,这种方式降低了存储的成本,并 且数据在主实例与读副本间复制数据带来的性能开销很小。
您的应用程序使用Aurora Connection Endpoint连接到一个Aurora集群。Connection Endpoint表示一个包含主机地址和端口的特定URL。当您创建一个Aurora实例时,AWS会在集群级和实例级创建端点。在集群级别,创建了两个端点,一个用于读/写操作(称为集群端点),另一个用于只读操作(称为只读端点)。故障转移可以通过集群端点实现,通过只读端点实现跨多个Read Replicas的负载平衡。但如果您使用的是实例的Endpoint,那么会固定连接到该Endpoint对应的数据库实例上。
当Aurora集群的主实例发生故障时,Aurora会按照如下顺序自动进行故障切换:
- 如果Aurora Read Replicas可用,将现有的Read Replica提升到新的主实例。
- 如果没有可用的读副本,则创建一个新的主实例。
- 如果有多个Aurora Read Replicas,则根据Read Replicas定义的优先级讲优先级最高的Replica提升为主实例。优先级号取值范围为0 ~ 15,可以随时修改。
关于Aurora Failover的详细原理与流程分析您可以参考另外一篇blog:居安思危 – Amazon Aurora 故障恢复性能提升方案
在实际开发中,我们发现应用层由于使用的JDBC连接池、JDBC driver、以及DNS配置的过期时间不同,应用程序从Aurora Failover中恢复的时间各不相同,因此本篇blog对相关的影响因素进行对比测试,可以给大家选择合适的驱动和连接池提供一些指引。
2. 环境搭建
2.1 搭建Aurora集群
首先根据Aurora集群创建指南创建一套Aurora MySQL集群,机型为db.r5.2xlarge,每套集群有一个写节点两个读节点。
2.2 准备测试Demo
git clone
https://github.com/arch-team/spring-boot-sharding-sphere.git
spring-boot-sharding-ssphere # 父工程
| #实现读写分离功能
---db-read-write
| #实现分表功能
---sub-table
| #实现分库分表功能
---sub-db-table
| #实现分表 + 读写分离
---sub-table-read-write
| #实现分库分表 + 读写分离
---sub-db-table-read-write
这里配置了两个slave,实际测试Aurora Failover您可以使用一主一从即可。
mybatis.config-location=classpath:mybatis-config.xml
server.port=8088
#JDBC驱动实现,本实验您需要使用不同driver来做测试,每个测试场景都需要修改
spring.shardingsphere.datasource.master.driver-class-name=software.aws.rds.jdbc.mysql.Driver
spring.shardingsphere.datasource.master.password=
spring.shardingsphere.datasource.master.type=com.alibaba.druid.pool.DruidDataSource
#Aurora 读写Endpoint URL,每个测试场景都需要修改
#jdbc:mysql:aws://db-identifier.cluster-XYZ.us-east-2.rds.amazonaws.com:3306
spring.shardingsphere.datasource.master.url=
spring.shardingsphere.datasource.master.username=
spring.shardingsphere.datasource.names=master,slave0,slave1
#JDBC驱动实现,本实验您需要使用不同driver来做测试,每个测试场景都需要修改
spring.shardingsphere.datasource.slave0.driver-class-name=software.aws.rds.jdbc.mysql.Driver
spring.shardingsphere.datasource.slave0.password=
spring.shardingsphere.datasource.slave0.type=com.alibaba.druid.pool.DruidDataSource
#Aurora 读写Endpoint URL,每个测试场景都需要修改
#jdbc:mysql:aws://aurora-sharding-sphere.cluster-ro-****.us-east-2.rds.amazonaws.com:3306/dev?useSSL=false&characterEncoding=utf-8
spring.shardingsphere.datasource.slave0.url=
spring.shardingsphere.datasource.slave0.username=
#JDBC驱动实现,本实验您需要使用不同driver来做测试,每个测试场景都需要修改
spring.shardingsphere.datasource.slave1.driver-class-name=software.aws.rds.jdbc.mysql.Driver
spring.shardingsphere.datasource.slave1.password=
spring.shardingsphere.datasource.slave1.type=com.alibaba.druid.pool.DruidDataSource
#Aurora 读写Endpoint URL,每个测试场景都需要修改
#jdbc:mysql:aws://salve1.***.us-east-2.rds.amazonaws.com:3306/dev?useSSL=false&characterEncoding=utf-8
spring.shardingsphere.datasource.slave1.url=
spring.shardingsphere.datasource.slave1.username=admin
spring.shardingsphere.masterslave.load-balance-algorithm-type=round_robin
spring.shardingsphere.masterslave.master-data-source-name=master
spring.shardingsphere.masterslave.name=ms
spring.shardingsphere.masterslave.slave-data-source-names=slave0,slave1
#spring.shardingsphere.mode.type=Memory
spring.shardingsphere.props.sql.show=true
如下图所示,在不同的测试场景下,需要修改依赖的Jdbc client driver。
本测试中我们主要验证Aurora Failover的功能,因此在本实验中只需要使用db-read-write子工程。
3. 基于 AWS JDBC Driver的时延测试
3.1 测试配置说明
修改./spring-boot-sharding-sphere/pom.xml文件中Jdbc Driver依赖的Jar,替换成
<dependency>
<groupId>software.aws.rds</groupId>
<artifactId>aws-mysql-jdbc</artifactId>
<version>1.0.0</version>
</dependency>
关于aws-mysql-jdbc详细介绍参照GitHub
https://github.com/awslabs/aws-mysql-jdbc
参照2.2 准备测试Demo中的application.properties配置文件说明,你需要修改的项包括如下的内容,其中每个DataSource包括master和slave都需要修改如下内容
**省略相同的内容**.***数据源标识***.driver=
**省略相同的内容**.***数据源标识***.username=
**省略相同的内容**.***数据源标识***.password=
**省略相同的内容**.***数据源标识***.url=
spring.shardingsphere.datasource.master.username=
spring.shardingsphere.datasource.master.driver-class-name=software.aws.rds.jdbc.mysql.Driver
spring.shardingsphere.datasource.master.password=
spring.shardingsphere.datasource.master.type=com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.master.url=
其中driver替换成software.aws.rds.jdbc.mysql.Driver
username:您的Aurora 集群用户名
password:您的Aurora 集群密码
url:Aurora Endpoint URL
使用druid作为连接池
type:com.alibaba.druid.pool.DruidDataSource
jdbc:mysql:aws://*集群名称*.*集群id*.us-east-2.rds.amazonaws.com:3306/*数据库名*?useSSL=false&characterEncoding=utf-8
注意:使用aws jdbc driver 数据库的url前缀需要使用jdbc:mysql:aws
3.2 测试过程说明
在./spring-boot-sharding-sphere/db-read-write/src/main/java/com/oujiong/Application.java上执行 Run AS。
如下图所示本次测试使用的是(AWS) JDBC Driver for MySQL
重复执行该方法,观测该REST API执行是否成功。
- 在Aurora的console上手动执行Aurora Failover。
3.3 测试结果说明
API调用恢复过程的时间记录,大约是5秒钟;多次测试记录Failover时应用层的恢复时间大概在4~8秒钟之间。
<> 2022-04-15T123025.200.txt
<> 2022-04-15T123023.200.txt # Failover恢复API支持成功的时间
<> 2022-04-15T123022.500.json # API执失败的实际
<> 2022-04-15T123017.200.txt # 最近一次执行成功的实际
<> 2022-04-15T123015.200.txt
<> 2022-04-15T123013.200.txt
API调用失败的异常信息
Error updating database. Cause: java.sql.SQLException: The active SQL connection has changed due to a connection failure. Please re-configure session state if required.
The error may exist in mapper/UserMapper.xml
The error may involve com.oujiong.mapper.UserMapper.insert-Inline
The error occurred while setting parameters
SQL: insert into tab_user (id, name, sex, age, create_time, update_time, status) values (?, ?, ?, ?, ?, ?, ?)
Cause: java.sql.SQLException: The active SQL connection has changed due to a connection failure. Please re-configure session state if required.
; The active SQL connection has changed due to a connection failure. Please re-configure session state if required.; nested exception is java.sql.SQLException: The active SQL connection has changed due to a connection failure. Please re-configure session state if required.] with root cause
如下图所示Aurora执行Failover 读写器从salve1变成了aurora-sahrding-sphere-instance-1-us-east-2a
4.基于mysql-connector/J的时延测试
4.1 测试配置说明
修改./spring-boot-sharding-sphere/pom.xml文件中的Jdbc Driver依赖Jar,替换成
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
关于mysql-connector-j详细介绍参照GitHub
https://github.com/mysql/mysql-connector-j
参照2.2 准备测试Demo中的application.properties配置文件说明,你需要修改的项包括如下的内容,其中每个DataSource包括master和slave都需要修改如下内容
**省略相同的内容**.***数据源标识***.driver=
**省略相同的内容**.***数据源标识***.username=
**省略相同的内容**.***数据源标识***.password=
**省略相同的内容**.***数据源标识***.url=
spring.shardingsphere.datasource.master.username=
spring.shardingsphere.datasource.master.driver-class-name=software.aws.rds.jdbc.mysql.Driver
spring.shardingsphere.datasource.master.password=
spring.shardingsphere.datasource.master.type=com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.master.url=
其中driver替换成com.mysql.jdbc.Driver
username:您的Aurora 集群用户名
password:您的Aurora 集群密码
url:Aurora Endpoint URL
jdbc:mysql://*集群名称*.*集群id*.us-east-2.rds.amazonaws.com:3306/*数据库名*?useSSL=false&characterEncoding=utf-8
注意:使用mysql-connector/J数据库的url前缀需要使用jdbc:mysql
4.2 测试过程说明
在./spring-boot-sharding-sphere/db-read-write/src/main/java/com/oujiong/Application.java上执行 Run AS。
本次测试使用的是mysql-connector/J
重复执行该方法,观测该REST API执行是否成功。
- 在Aurora的console上手动执行Aurora Failover
4.3 测试结果说明
API调用恢复过程的时间记录,大约是45秒钟;多次测试记录Failover应用层的恢复时间大概在30~50多秒钟之间。
<> 2022-04-15T125920.200.txt
<> 2022-04-15T125918.200.txt # Failover恢复API支持成功的时间
<> 2022-04-15T125909.500.json # API执失败的实际
<> 2022-04-15T125904.500.json # API执失败的实际
<> 2022-04-15T125900.500.json # API执失败的实际
<> 2022-04-15T125855.500.json
<> 2022-04-15T125849.500.json # API执失败的实际
<> 2022-04-15T125844.500.json # API执失败的实际
<> 2022-04-15T125840.500.json # API执失败的实际
<> 2022-04-15T125834.500.json # API执失败的实际
<> 2022-04-15T125833.200.txt # 最近一次执行成功的实际
<> 2022-04-15T125831.200.txt
API调用失败的异常信息
2022-04-15 12:58:33.975 INFO 26782 --- [nio-8088-exec-7] ShardingSphere-SQL : Rule Type: master-slave
2022-04-15 12:58:33.975 INFO 26782 --- [nio-8088-exec-7] ShardingSphere-SQL : SQL: insert into tab_user (id, name, sex,
age, create_time, update_time,
status)
values (?, ?, ?,
?, ?, ?,
?) ::: DataSources: master
2022-04-15 12:58:33.989 ERROR 26782 --- [nio-8088-exec-7] com.alibaba.druid.pool.DruidDataSource : discard connection
java.sql.SQLException: Could not retrieve transaction read-only status from server
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:965) ~[mysql-connector-java-5.1.47.jar:5.1.47]
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:898) ~[mysql-connector-java-5.1.47.jar:5.1.47]
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:887) ~[mysql-connector-java-5.1.47.jar:5.1.47]
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:861) ~[mysql-connector-java-5.1.47.jar:5.1.47]
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:878) ~[mysql-connector-java-5.1.47.jar:5.1.47]
如下图所示Aurora执行Failover ,读写器从aurora-sahrding-sphere-instance-1-us-east-2a变成了salve1
5. 基于MariaDB Connector/J的时延测试
5.1 测试配置说明
修改./spring-boot-sharding-sphere/pom.xml文件中的Jdbc Driver依赖Jar,替换成
<dependency>
<groupId>org.mariadb.jdbc</groupId>
<artifactId>mariadb-java-client</artifactId>
<version>3.0.4</version>
</dependency>
关于mariadb-connector-j详细介绍参照GitHub
https://github.com/mariadb-corporation/mariadb-connector-j
参照2.2 准备测试Demo中的application.properties配置文件说明,你需要修改的项包括如下的内容,其中每个DataSource包括master和slave都需要修改如下内容
**省略相同的内容**.***数据源标识***.driver=
**省略相同的内容**.***数据源标识***.username=
**省略相同的内容**.***数据源标识***.password=
**省略相同的内容**.***数据源标识***.url=
spring.shardingsphere.datasource.master.username=
spring.shardingsphere.datasource.master.driver-class-name=software.aws.rds.jdbc.mysql.Driver
spring.shardingsphere.datasource.master.password=
spring.shardingsphere.datasource.master.type=com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.master.url=
其中driver替换成org.mariadb.jdbc.Driver
username:您的Aurora 集群用户名
password:您的Aurora 集群密码
url:Aurora Endpoint URL
jdbc:mariadb://*集群名称*.*集群id*.us-east-2.rds.amazonaws.com:3306/*数据库名*?useSSL=false&characterEncoding=utf-8
注意:使用mariadb-java-client数据库的url前缀需要使用jdbc:mariadb
5.2 测试过程说明
与基于mysql-connector/J的时延测试章节的内容类似,这里不再重复描述。
5.3 测试结果说明
在分别使用mariadb-java-client 3.0.4 和 1.1.9 发现如下问题,采用mariadb-java-client应用层从Failover中恢复的时间高达十来分钟。
<> 2022-04-15T211640.200.txt
<> 2022-04-15T213015.200.txt
<> 2022-04-15T213003.200.txt # Failover恢复API支持成功的时间
<> 2022-04-15T212952.500.json
<> 2022-04-15T212511.500.json
<> 2022-04-15T212230.500.json
<> 2022-04-15T211653.500.json
<> 2022-04-15T211642.500.json # API执失败的实际
<> 2022-04-15T211641.200.txt # 最近一次执行成功的实际
其中上层API调用的报错信息如下:
“timestamp”: “2022-04-15T13:39:26.858+0000”,
“status”: 500,
“error”: “Internal Server Error”,
“message”: “\n### Error updating database. Cause: java.sql.SQLException: (conn=5) The MySQL server is running with the —read-only option so it cannot execute this statement\n### The error may exist in mapper/UserMapper.xml\n### The error may involve com.oujiong.mapper.UserMapper.insert-Inline\n### The error occurred while setting parameters\n### SQL: insert into tab_user (id, name, sex, age, create_time, update_time, status) values (?, ?, ?, ?, ?, ?, ?)\n### Cause: java.sql.SQLException: (conn=5) The MySQL server is running with the —read-only option so it cannot execute this statement\n; uncategorized SQLException; SQL state [HY000]; error code [1290]; (conn=5) The MySQL server is running with the —read-only option so it cannot execute this statement; nested exception is java.sql.SQLException: (conn=5) The MySQL server is running with the —read-only option so it cannot execute this statement”,
“path”: “/save-user”
6. 基于RDS Proxy的时延
RDS Proxy的测试可以通过直接连接Proxy的Endpoint执行SQL即可,本篇blog不做描述,如果您决定在生产上使用RDS Proxy它可以有效降低Failover的恢复时间,考虑在服务端降低Failover 恢复时间可以使用这种方案。
使用RDS Proxy Failover 恢复时间的测试,请参考另外一篇blog
居安思危 – Amazon Aurora 故障恢复性能提升方案
7. 结论
影响Amazon Aurora for MySQL的时延因素包括如下方面
1、使用SQL Driver,包括
mariadb-java-client
aws-mysql-jdbc
mysql-connector-java
2、使用的数据库连接池
综合测试结果来看aws-mysql-jdbc与druid 或者 HikariCP Failover的时延都比较短,大概在7~8秒左右;druid 与 aws-mysql-jdbc或者mariadb-java-client Failover恢复时间大概在40秒左右。HikariCP 与mysql-connector-java和mariadb-java-client Failover 恢复时间在分钟级别。
注意:以上的测试数据是基于通过公网连接Aurora进行的,另外由于使用的中间件不同,中间件的版本也有区别,另外本篇blog主要关注Aurora Failover恢复的时间,实际使用中还需要关注性能、连接的稳定性等,因此上述测试数据仅供参考,生产使用时要评估Aurora Failover的时间,建议以您实际的部署环境和真实使用的软件系统为基准进行测试。
8.参考资料
https://aws.amazon.com/cn/blogs/database/improve-application-availability-with-the-aws-jdbc-driver-for-amazon-aurora-mysql/
https://aws.amazon.com/cn/blogs/database/failover-with-amazon-aurora-postgresql/
https://crishantha.medium.com/aws-aurora-why-is-it-better-6faae33a0ed0
9.问题记录
在使用hikari时,数据库连接的url配置的应该使用jdbc-url,而不是url;在使用druid作为连接池时,应该使用的url。
spring.shardingsphere.datasource.ds_master.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.ds_master.jdbc-url=***
springboot配置文件中不能有空格,如下的包名加了空格的话会提示找不到HikariDataSource
com.zaxxer.hikari.HikariDataSource
相关博客
居安思危 —— Amazon Aurora 故障恢复之降低DNS切换对应用影响篇
本篇作者