亚马逊AWS官方博客

Aurora MySQL 2 升级之蓝绿部署切换后自动搭建 DMS 回滚复制的方案

背景

Aurora 是亚马逊云科技提供的一个与 MySQL 和 PostgreSQL 兼容的完全托管的关系数据库服务。Aurora MySQL 2 即将在 2024 年 10 月 End of Life,因此使用 Aurora MySQL 2 的客户需要升级到 Aurora MySQL 3,并且对应用程序做兼容性修改和测试。测试通过后,进行正式的数据库升级操作。很多客户做升级操作时选择蓝绿部署的方案,亚马逊云科技提供了一键蓝绿部署方案,帮助客户非常方便地把 Aurora MySQL 2 升级到 Aurora MySQL 3。同时,很多客户为了升级方案更加完备,会增加回滚方案,即在蓝绿部署切换后,需要搭建 1 个从新主集群到旧蓝集群的数据复制链路,目的是把新主集群的数据变化准实时同步回旧的蓝环境。目前蓝绿部署切换暂不支持自动搭建回滚复制,用户可以先修改旧蓝集群的 read_only 为 OFF 后,搭建回滚复制链路,一般可以采用 MySQL 原生复制、DMS CDC 任务或其他支持 MySQL 复制的数据同步工具。本文提供一种方案,自动捕捉蓝绿部署切换完成的事件,调用 Lambda Function,利用 DMS CDC 复制任务,自动搭建回滚复制链路。

解决方案概览

整体方案如下图:

Aurora 蓝绿部署创建、切换、切换完成,会向 Events 输出相应事件,EventBridge 可以发现这些事件并根据规则推送给 Lambda 。我们可以通过编写 Lambda Function 实现事件过滤,发现蓝绿部署 SwitchOver 完成的事件:RDS-EVENT-0260 ,触发调用 DMS API,自动搭建从 Aurora MySQL 3 到 Aurora MySQL 2 的 CDC 复制链路的方案,加快回流复制链路的配置,提升 Aurora MySQL 2 升级方案完整性。参考:具体 RDS 事件类型 Blue/green deployment events

前提条件

  • 已有的 Aurora MySQL 2 集群位于 VPC 的私有子网,且子网状态为 Available
  • 提前在与 Aurora MySQL 2 集群相同的 AZ 和 VPC 内创建 1 个 DMS 复制实例

部署方法概览

多个 Aurora 集群做升级,以下部署步骤都只需要部署一次即可。

  • 创建 Lambda function,将 AWS Lambda 与 Amazon Aurora 结合使用
  • 创建 Lambda Function 的执行角色
  • 为 Lambda Function 创建 RDS VPC endpoint
  • 为 Lambda Function 创建 DMS VPC endpoint
  • 创建 1 个 EventBridge 的 Rule,只推送 RDS Blue Green Deployment Event 到 Lambda function
  • 上传 Lambda 代码更新 Function,并 Deploy 代码

使用方法概览

每个 Aurora 集群升级时,按照如下步骤使用。

  • 创建 Aurora 蓝绿部署,绿环境的 Aurora MySQL 3 启用 Binlog,创建用于复制的帐号
  • 把以上蓝绿环境的信息配置为 Lambda 环境变量(集群 ID、Region、复制账号密码)
  • 开始集群蓝绿部署切换

风险

  • 蓝绿部署切换完成后,这个集群的蓝绿环境的 DB identifier 会被 Lambda Function 删除,Console 上看不到该集群的 Blue/Green Deployment 这个标识(与手动删除的结果一致)
  • Lambda Function 会修改旧蓝环境 read_only 为 OFF,以便搭建回流复制链路,旧蓝环境为可写,为了避免发生双写,您需要防止应用切换不完全而写入旧蓝环境,避免导致数据错乱。

部署方法

1. 创建 AWS Lambda Function 与 Amazon Aurora 结合使用

创建关联 Aurora 的 Lambda 函数

选择你 VPC 内的其中 1 个 Aurora 数据库集群即可,Lambda 一次部署后,可适用于 VPC 内所有 Aurora 集群;并从操作中选择设置 Lambda 连接,可参考:教程:使用 Lambda 函数访问 Amazon RDS 数据库

选中你的 Aurora 集群,点击 Actions,然后选择 Set up Lambda connection。在 Set up Lambda connection 页面,选择 Create new function 按钮。输入 Lambda function nameLambdaFunctionWithRDS,可以自定义名字,不需要勾选 RDS Proxy 选项。然后,选择 Set up 完成 Lambda function 创建。

  • 设置 Runtime

创建完成后,进入 Lambda function 页面,点击 LambdaFunctionWithRDS,在页面下方找到 Runtime settings 并编辑,Runtime 选择 Python 3.10;将 Handler 输入 lambda_function.lambda_handler,然后保存。

  • 设置 VPC、子网与安全组

点击 Configuration 选项卡,再选择左边的导航栏的 VPC,点击 Edit,选择与 Aurora 数据库集群相同的 Security groups,如下图是 default 安全组,注:VPC、子网已在创建时与数据库集群保持一致。由于需要访问 RDS 和 DMS 的 API 服务,因此需要确保安全组 Outbound rules 中存在 1 条出站规则:允许 Lambda function 向 AWS 服务发起请求 。如下:

设置 Lambda 函数的执行超时时间

考虑蓝绿部署切换、确认集群状态、取消旧蓝环境只读设置等过程的时长,建议设置为 15 分钟。进入 Lambda console,选择刚刚创建的 Function ,点击 Configuration,在 General configuration 中把 Timeout 设置为 15min 0sec这样做是因为该 Function 在后台运行需要一段时间检查环境并最终执行。

2. 创建 Lambda Function 的执行角色

打开 IAM 控制台的角色页面,并选择创建角色。对于可信实体类型 Trusted entity type,请选择 AWS 服务,对于 Use case请选择 Lambda。选择 Next,通过以下方式添加 IAM 托管策略:

使用策略搜索框,搜索 AWSLambdaVPCAccessExecutionRole,在搜索结果列表中,选中该角色旁边的复选框,即选定了权限。然后选择 Clear filters,继续添加其他权限

继续用相同的方式添加其他角色,本次一共需要 3 个角色和 1 个 DMS 使用权限:

  • AmazonRDSFullAccess – 授权 Lambda 查看 Aurora 集群的 Endpoint 等信息,并不查询表数据
  • AWSLambdaVPCAccessExecutionRole – 授权 Lambda 可以访问和使用 VPC
  • CloudWatchLogsFullAccess – 授权 Lambda 把日志输出到 CloudWatch Logs

继续添加使用 DMS 的权限。参考方法:Adding IAM identity permissions,使用如下 JSON 配置:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "id0",
            "Effect": "Allow",
            "Action": [
                "dms:StartReplicationTask",
                "dms:CreateEndpoint",
                "dms:StopReplicationTask",
                "dms:TestConnection",
                "dms:CreateReplicationTask",
                "dms:DescribeReplicationTasks"
            ],
            "Resource": "*"
        }
    ]
}

点击 Next,输入自定义的角色名字 lambda-vpc-sqs-role 作为 Role name然后点击 Create role 完成角色创建创建完成后,编辑 LambdaFunctionWithRDSGeneral configuration,把 Execution role 更新为 lambda-vpc-sqs-role,保存。

3. 为 Lambda Function 创建 1 个访问 RDS Service 的 VPC endpoint

由于 Aurora 位于 Private subnet,以上方法创建的 Lambda Function 也位于相同的 Private subnet,而 Lambda Function 需要通过 Python SDK 访问 AWS RDS API,有两个通常的做法,具体参考:为连接到 VPC 的 lambda 函数提供互联网和服务访问。一是通过配置 NAT + Internet Gateway 方式通过公网访问,二是为 Lambda function 创建 RDS service 的 VPC endpoint,推荐使用方法二:创建 VPC endpoint。按照链接中的指示,Name tag 输入 endpoint 名字:lambda-rds-vpc-endpoint, Services 输入 RDS 并根据 Aurora 服务所在 region,选择: com.amazonaws.ap-northeast-1.rds, VPC 选择 lambda function 所在VPC,Subnets 的 3 个 AZ 分别勾选 1 个 Subnet,请选择 lambda 所在 Subnet;Security Group 添加以上产生的默认安全组,如:default, 然后点击“Create Endpoint”即可。本例中修改为 Private subnet: RDS-Pvt-subnet-2。如下图:

注意:确认 lambda funciton 所在 Subnet 的方法如下

4. 为 Lambda Function 创建 1 个访问 DMS Service 的 VPC endpoint

方法与创建访问 RDS Service 的 VPC endpoint 相同。Name tag 输入 endpoint 名字:lambda-dms-vpc-endpoint,Services 输入 DMS 并选择:com.amazonaws.ap-northeast-1.dms,VPC 选择 lambda function 所在 VPC,Subnets 的 3 个 AZ 分别勾选 1 个 Subnet,请选择 lambda 所在 Subnet,Security Group 添加以上产生的默认安全组,如:default, 然后点击“Create Endpoint”即可。

5. 创建 EventBridge 的规则

该规则主要为了订阅 RDS 的蓝绿部署相关的事件,并推送给 Lambda 函数,具体方法参考:Creating a rule that triggers on an Amazon RDS event

Event pattern 部分按照下图选择,标识指推送蓝绿部署相关事件给 Target。

下一步,Target 选择 Lambda function,Function 选择上文创建的 LambdaFunctionWithRDS

点击 Next 后全部默认值完成创建。

6. 编写 Lambda Function 代码

代码主要实现自动搭建从新主集群到旧蓝集群的 DMS CDC 复制链路,有如下几个功能:

  1. 接收 Eventbridge 的通知
  2. 获取所有 Aurora 集群蓝绿切换的集群的详细信息
  3. 获取蓝绿部署切换的时间,切换的源和目标的信息
  4. 获取蓝绿部署切换后用于下游复制的 Binlog 文件和 Position
  5. 删除用户配置在 Lambda 环境变量中的集群 ID 对应的蓝绿部署
    • 切换成功后,Aurora 旧的蓝数据库实例是只读的
    • 删除蓝绿部署,自动把旧蓝色环境的 read_only 设置为 OFF
    • 该过程持续持续几分钟,因此 Lambda 程序会等待 read_only=OFF 后再去执行下一步
  6. 调用 DMS 搭建 CDC 复制链路

Lambda 代码可参考 Demo

7. 打包代码并更新 Lambda Function

把代码打包

将以上示例代码保存为一个名为 lambda_function.py 的文件。

在你创建 lambda_function.py 文件的同一个目录下,创建一个新目录名为 package,并安装 PyMySQL 库。

mkdir package
pip install --target package pymysql

创建一个 zip 文件,其中包含你的应用程序代码和 PyMySQL 库。在 Linux 或 MacOS 中,运行以下 CLI 命令:

cd package
zip -r ../lambda_function.zip .
cd ..
zip lambda_function.zip lambda_function.py

如果你使用 Windows,使用你偏好的 zip 工具创建 lambda_function.zip 文件。

注意:你的 lambda_function.py 源代码文件和包含依赖项的文件夹必须安装在 .zip 文件的根目录下。

更新 Lambda Function

用打包好的代码更新 Lambda Function,具体方法参考:vpc-rds-update-function

以上部署一次后,在这个 VPC 内的其他 Aurora 集群都可使用,不需要每个 Aurora 单独部署 Lambda。以下是该方案的具体使用方法。

使用方法

1. 创建 Aurora 蓝绿部署环境

选择本次要升级的 Aurora MySQL 2 集群,创建蓝绿部署具体方法与官网一致,请参考:创建蓝绿部署。蓝绿环境部署成功后,进行如下步骤。

绿集群开启 Binlog

注意需要自定义参数组,并应用到绿集群,并重启绿集群。确认方法如下:

show master status 有 binlog 输出;binlog_format 未显示 OFF

mysql> show master status;
+----------------------------+----------+--------------+------------------+-------------------+
| File                       | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+----------------------------+----------+--------------+------------------+-------------------+
| mysql-bin-changelog.000008 |      157 |              |                  |                   |
+----------------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)

mysql> show variables like 'binlog_format';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| binlog_format | ROW   |
+---------------+-------+
1 row in set (0.00 sec)

在绿环境创建复制账号

使用管理员账户登陆 Aurora 绿环境执行

mysql> CREATE USER 'repl_user'@'%' IDENTIFIED WITH mysql_native_password BY '<YourPassword>';

mysql> GRANT REPLICATION CLIENT, REPLICATION SLAVE ON *.* TO 'repl_user'@'%';

mysql> GRANT SELECT ON *.* TO 'repl_user'@'%';
mysql> flush privileges;

调整绿环境 Binlog 保留时间

根据业务需要调整 Binlog 保留时间,最大可设置 168 小时

mysql> call mysql.rds_set_configuration('binlog retention hours', 72);

mysql> call mysql.rds_show_configuration;
+------------------------+-------+------------------------------------------------------------------------------------------------------+
| name                   | value | description                                                                                          |
+------------------------+-------+------------------------------------------------------------------------------------------------------+
| binlog retention hours | 72    | binlog retention hours specifies the duration in hours before binary logs are automatically deleted. |
+------------------------+-------+------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)

2. 配置 Lambda 函数的环境变量

在 Lambda 控制台的函数页面中,选择配置选项卡,然后选择环境变量

选择编辑,主要配置本次蓝绿切换的 Aurora MySQL 2 数据库访问凭证,请执行以下操作:

选择添加环境变量,Key 输入 CLUSTER_ID,然后 Value 输入您本次升级切换的集群 ID。

选择添加环境变量,Key 输入 USER_NAME,然后 Value 输入创建 Aurora MySQL 2 时设置的管理员用户 admin

选择添加环境变量,Key 输入 PASSWORD,然后 Value 输入您在创建 Aurora MySQL 2 数据库时设置的密码。

选择添加环境变量,Key输入 REGION,然后 Value 输入您本次升级切换的集群所在 Region。如:ap-northeast-1

选择添加环境变量,Key 输入 REPL_USER,然后 Value 输入您创建的用于复制的用户。

选择添加环境变量,Key 输入 REPL_PASS,然后 Value 输入您创建的用于复制的用户的密码。

选择添加环境变量,Key 输入 BINLOG_MSG,【Value 可选】Value 可以用于指定 BINLOG 文件和位置(主要用于问题修复),自动搭建时,会从 Event 自动获取 Binlog,因此这里不需要指定 Binlog,但 Key(BINLOG_MSG)仍然要输入。

选择添加环境变量,Key 输入 REP_INSTANCE_ARN,然后Value输入您创建的用于复制的 DMS 复制实例的 ARN 资源标识符。

选择添加环境变量,Key 输入 CDC_METHOD,然后 Value 输入您选用的数据回流方式,有两个值 DMS_CDC(表示采用 DMS)或 MY_REPLICATION(表示采用 MySQL 原生复制),建议使用 DMS_CDC

选择 Save(保存)。回到 Lambda Code 页面,确保 Lambda 最新代码已经 Deploy 成功。

2. 切换蓝绿部署

切换方法,请参考:blue-green-deployments-switching.html

3. 查看 Lambda 执行情况

当看到蓝绿部署切换完成时,Lambda 函数开始自动执行,校验 Aurora 集群信息和切换状态符合要求后,蓝绿部署的标志会进入 Deleting 状态,如下图:

蓝绿部署的 Blue/Green Deployment 被删除后(Console 上这个角色的 identifier:如 my-blue-green-deployment 会消失),进入搭建回流复制链路的流程。可以通过 Lambda 的 Monitor 选项卡中,点击 View CloudWatch Logs,进行最新的 log stream 查看 Lambda 执行情况。

当看到如下日志时,Lambda 执行完成:

[INFO] 2024-07-24T07:17:32.305Z Begin to start cdc task: arn:aws:dms:ap-northeast-1:730xxxxxx650:task:RJO5HWZGxxxxxxxxx
[INFO] 2024-07-24T07:17:33.505Z SUCCESS: set rollback replication for RDS/Aurora MySQL mydb1 succeeded

4. 检查 DMS 回滚复制链路搭建结果

登陆 DMS console,你会看到存在一个 CDC 同步任务,任务名是 cdc-after-bg-switch-<yourClusterId> ,并显示 Replication Ongoing 状态。此时,说明 Aurora 蓝绿部署切换后,已经自动搭建好了从 Aurora MySQL 3 向 Aurora MySQL 2 的数据同步链路。

总结

数据回流复制预案是 Aurora MySQL 2 升级 Aurora MySQL 3 回滚预案的重要一环,本方案旨在帮助您使用蓝绿部署升级 Aurora MySQL 2 集群期间,利用 AWS DMS 自动搭建数据回流复制链路,让您升级 Aurora 集群更加便捷。在此示例中,数据库访问凭证将存储为环境变量,在实际使用中,建议您将 AWS Secrets Manager 用作更安全的选项。对于示例代码,后续也可根据需要增加云服务 API 连通性的部分代码与测试方法,方便实施过程中测试 DMS 和 RDS API 的连通性。

本篇作者

金川

亚马逊云科技数据库解决方案架构师,负责基于亚马逊云科技的数据库的解决方案咨询与架构设计。在加入亚马逊云科技之前曾在华为、阿里云等公司工作多年,在数据库选型与架构设计、数据库优化、数据迁移、大数据和数仓建设方面有丰富的技术经验,在金融、互联网、通信等行业有丰富的设计和实施经验。