MySQL Group Replication Plugin是一个社区插件,它建立在 Paxos 分布式算法的实现之上,允许最多九个数据库(DB)实例配置为active/active设置。对于任何事务提交,组中的大多数 DB 实例必须就给定事务在全局事务序列中的顺序达成一致。
我们可以使用 MySQL Group Replication插件为 RDS for MySQL 设置active-active集群,  在 RDS for MySQL 数据库实例之间设置主动-主动复制,为我们的应用程序提供持续可用性。在主动-主动集群中向两个或更多数据库实例写入数据可以帮助最大化可用性并减少写入延迟。
Group Replication插件在 Amazon RDS for MySQL 8.0.35 及更高版本中可用。
有关 MySQL Group Replication的信息,请参见 MySQL 文档中的Group Replication
和Group Replication协议
。
下图说明了Group Replication体系结构:

过程如下:
配置 RDS for MySQL 实例的参数组
在 RDS for MySQL 实例之间配置Active-active复制
监控Active-active复制
测试Active-active复制
本节总共用到三个RDS实例,在它们之间进行Active-active复制。
先基于原来的RDS实例创建两个replica,再将它们promote成单独集群。创建read replica:

其他选项不变,将identifier分别命名为my-instance-2和my-instance-3:

创建完成两个read replica后,分别将其promote:

使用 MySQL8 的默认配置创建一个参数组

命名为group-replication-pg, 选择mysql 8.0:

创建完成后:

使用以下参数修改参数组 (group-replication-pg) 以配置 MySQL active-active复制:
aws rds modify-db-parameter-group \
    --db-parameter-group-name group-replication-pg \
    --parameters "ParameterName=binlog_format,ParameterValue=ROW,ApplyMethod=pending-reboot" \
                 "ParameterName=group_replication_group_name,ParameterValue=9510b991-99b4-11ee-8669-0a9258440a9f,ApplyMethod=pending-reboot"\
                 "ParameterName=enforce_gtid_consistency,ParameterValue=ON,ApplyMethod=pending-reboot"\
                 "ParameterName=rds.group_replication_enabled,ParameterValue=1,ApplyMethod=pending-reboot"\
                "ParameterName=rds.custom_dns_resolution,ParameterValue=1,ApplyMethod=pending-reboot"\
                 "ParameterName=gtid-mode,ParameterValue=ON,ApplyMethod=pending-reboot"\
                 "ParameterName=slave_preserve_commit_order,ParameterValue=1,ApplyMethod=pending-reboot"
为上述创建的参数组修改了以下参数:
| 参数名称 | 值 | 其他注释 | 
| binlog_format | ROW | 将 binlog_format的值设置为 ROW 是group replication正常工作的先决条件。此参数的默认值设置为 MIXED。 | 
| group_replication_group_name | 11111111-2222-3333-4444-555555555555 | 可以将其修改为使用我们自己的 UUID。 | 
| gtid_mode | ON | 用于跟踪每个服务器实例上已提交的事务。这是 group replication正常工作的先决条件。 | 
| enforce_gtid_consistency | ON | 这是 group replication正常工作的先决条件。 | 
| rds.custom_dns_resolution | 1 | 此参数指定是否允许从 VPC 中的 Amazon DNS 服务器进行 DNS 解析。启用组复制时,必须启用 DNS 解析 | 
| rds.group_replication_enabled | 1 | 在集群上启用 group replication功能 | 
| slave_preserve_commit_order | ON | 此参数是必需的,以确保在并行执行事务时在每个 DB 实例上维护正确的事务顺序 | 
首先,我们需要获取创建的 RDS for MySQL 实例的所有endpoint,以在active-active集群中使用。
group_replication_group_seeds_list=$(aws rds describe-db-instances --output text --query 'DBInstances[].[Endpoint.Address]'|sed 's/$/:3306/'|sed ':a;N;$!ba;s/\n/\\,/g')
确认上述命令的输出,在此列表中,我们将有所有 RDS 实例endpoint,用 “,” 分隔。
echo $group_replication_group_seeds_list

现在我们有了所有 RDS for MySQL endpoint,为了在与每个 DB 实例关联的 DB 参数组中配置参数 group_replication_group_seeds,运行以下 modify-db-parameter-group
 CLI 命令:
aws rds modify-db-parameter-group --db-parameter-group-name group-replication-pg --parameters ParameterName=group_replication_group_seeds,ParameterValue=$group_replication_group_seeds_list,ApplyMethod=immediate
通过使用以下查询确认所有 RDS for MySQL 实例 (rdslab-group-mysql1、rdslab-group-mysql2 和 rdslab-group-mysql3) 处于 “available” 状态:
aws rds describe-db-instances --query 'DBInstances[].[DBInstanceIdentifier,Endpoint.Address,DBInstanceStatus]'

然后修改几个实例的DB Parameter group,使用上面新建的group-replication-pg, 并选择立即应用:

应用完成后,将三个实例分别重启,这样新的参数组才能生效。等待几个实例全部变成可用状态:

在配置 RDS 实例上的active-active集群之前,让我们设置group replication用户、group replication recover channel和二进制日志保留。
replication group用户
: 在 DB 实例上创建复制用户 rdsgrprepladmin 用于group replication。active-active集群中所有 DB 实例的 rdsgrprepladmin 用户密码必须相同。rdsgrprepladmin 用户名是group replicaion连接保留的。其他用户,包括主用户,都不能使用这个用户名。
replication group recovery channel
: 为active-active集群设置 group_replication_recovery 通道。更多信息请参见: replication channel
bin log保留时长
: 二进制日志保留时间参数用于指定在 DB 实例上保留bin log文件的小时数。Amazon RDS 通常会尽快清除二进制日志,因此bin log对于复制active-active集群内的更改是必需的。
确保我们在active-active集群中的所有 RDS MySQL 实例上运行这些存储过程。
打开三个终端窗口,连接到所有 RDS for MySQL 实例:
mysql -u $DBUSER -p$DBPASS -h [endpoint]
运行以下存储过程来创建group replication用户 rdsgrprepladmin。rdsgrprepladmin 用户是active-active集群中group replication连接的保留用户。更多信息请参考管理主动-主动集群
。
call mysql.rds_group_replication_create_user('groupreplication');

创建group replication recovery channel。此存储过程为active-active集群设置 ‘group_replication_recovery’ 通道。该过程使用保留的 ‘rdsgrprepladmin’ 用户来配置通道。
call mysql.rds_group_replication_set_recovery_channel('groupreplication');
 将bin log保留配置为 7 天。我们可以根据需要调整此值。
将bin log保留配置为 7 天。我们可以根据需要调整此值。
call mysql.rds_set_configuration('binlog retention hours', 168);

通过在集群的一个 RDS for MySQL 实例上运行以下存储过程来启动集群。该语句在集群的一个 DB 实例上启动group replication。将存储过程 rds_group_replication_start
 的参数值设置为 1,表示我们正在引导集群。
确保我们只在主动-主动集群中的一个 RDS MySQL 实例上运行这些存储过程。例如: 我们可以在 DB 实例(rdslab-group-mysql1)上引导集群。
运行此命令来初始化复制组(仅在一个实例上运行一次)。此示例在 mysql.rds_group_replication_start 存储过程中指定 1 来初始化一个新group,其中包含当前的 DB 实例。
call mysql.rds_group_replication_start(1);
确认组复制已在该实例上成功启动。

现在,通过在集群的其余 RDS for MySQL 实例上运行存储过程 rds_group_replication_start,并将参数值设置为 0,来启动组复制。
call mysql.rds_group_replication_start(0);
确保我们在主动-主动集群中的其他两个 RDS for MySQL 实例上运行这些存储过程。
确认以下输出:
