新增 — 在亚马逊 Aurora PostgreSQL 和适用于 PostgreSQL 的亚马逊 RDS 中采用完全托管的蓝/绿部署

作者: Chirag Dave | 202 3

对数据库进行更新,例如重大升级、实例扩展和更改参数设置,在停机时间最少且不中断业务的情况下很难做到。即使进行了大量测试,直接更改生产环境也不一定是安全或快速的。直接更改可能会导致操作期间的停机时间延长。替代方案——创建一个镜像生产环境的暂存环境,在两个环境之间设置稳定的同步,然后执行低停机时间切换——更安全、更快,但并不简单。

例如,为了测试主要版本升级, Amazon Aurora 亚马逊关系数据库服务 (Amazon RDS) 支持一键就地升级主要版本。但是,在将更改推广到生产环境之前,客户更愿意在暂存环境中测试更改。Amazon Aurora 和 Amazon RDS 提供数据库 克隆 和可升级 只 读副本等 功能 ,以帮助他们自行管理暂存环境。要创建暂存环境,必须仔细协调设置,确保将生产设置正确复制到新数据库。由于与该任务相关的复杂性,您可以选择延迟数据库升级,选择可用性而不是升级数据库所获得的安全性、性能和功能优势。

对于需要更简单地编排创建暂存环境以进行广泛测试并在主要版本升级期间实现最大可用性的工作负载,我们很高兴地宣布,适用于亚马逊 Aurora PostgreSQ L 兼容版和适用于 PostgreSQL 的 Amaz on RDS 蓝/绿部署 适用于版本 11.21 及更高版本、12.16 及更高版本、13.12 及更高版本、14.9 及更高版本,以及所有适用的 亚马逊云科技 区域和 亚马逊云科技 GovCloud(美国)地区。

只需点击几下,您就可以创建蓝/绿部署,以创建镜像生产环境(蓝色)的单独的完全托管的暂存环境(绿色)。暂存环境克隆您的生产环境的主数据库和区域内只读副本。蓝/绿部署使用 PostgreSQL 社区提供的逻辑复制使这两个环境保持同步。

在短短一分钟内,您可以将暂存环境升级为新的生产环境,而不会丢失数据。在切换期间,蓝/绿部署会阻止对两个环境进行写入,以便绿色环境与生产数据库完全同步(蓝色)。蓝/绿部署将生产流量重定向到新推出的暂存环境,所有这些都无需更改任何代码来管理您的端点。

在这篇文章中,我们将介绍一个创建蓝/绿部署的示例。我们还将展示如何使用蓝/绿部署在最大限度地减少停机时间的情况下执行主要版本升级,并描述了切换过程。最后,我们将讨论使用蓝/绿部署的最佳实践。

解决方案概述

蓝/绿部署基于 PostgreSQL 逻辑复制。 物理复制使用精确的区块地址和逐字节复制,这可以防止两个主要版本之间的复制。相比之下,逻辑复制根据复制身份(通常是主键)复制表及其更改,这使我们能够在两个支持的 PostgreSQL 系统之间复制数据。

先决条件

首先,您需要 启用逻辑复制 并执行一次性就地将次要版本升级到支持蓝/绿部署的次要版本:

aws rds create-db-cluster-parameter-group \
--db-cluster-parameter-group-name pg14-blue-green \
--db-parameter-group-family aurora-postgresql14 \
--description "Parameter group that contains logical replication settings for Aurora PG 14" 

aws rds modify-db-cluster-parameter-group \
--db-cluster-parameter-group-name pg14-blue-green \
--parameters "ParameterName='rds.logical_replication',ParameterValue=1,ApplyMethod=pending-reboot" 

值得注意的是,除了启用逻辑复制外,根据您的数据库工作负载,您还需要调整以下参数,本文的最佳实践部分将进一步讨论这些参数。

max_replication_slots
max_wal_sender 
max_logical_replication_worker 
max_worker_processes

您也可以直接从 亚马逊云科技 管理控制台 修改参数组 。有关更多信息,请参阅 使用数据库参数组

如果您要将此参数添加到现有 Amazon Aurora 集群,则需要重启数据库以使设置生效。我们建议您更改这些参数,同时将次要版本就地升级到蓝/绿支持的引擎版本,以避免生产数据库多次重启。例如,如果你有一个名为 blue-gre en-inst01 的亚马逊 Aurora PostgreSQL 兼容实例 ,则可以使用以下命令将其重启:

aws rds reboot-db-instance \
  --db-instance-identifier blue-green-inst01 \
  --region "${REGION}"

启动绿色集群

您可以使用以下命令创建绿色集群,其中源是源生产数据库的 Amazon 资源名称 (ARN):

aws rds create-blue-green-deployment \
--blue-green-deployment-name my-blue-green-deployment \
--source arn:aws:rds:{REGION}:{ACCOUT_ID}:cluster:blue-green-cluster

创建完成后,您现在拥有一个可以进行测试和验证的暂存环境,然后再将其升级为新的生产环境。

有关分步指南,请参阅 Amazon Aurora 和 Amazon RDS 中的 全托管蓝/绿部署

使用蓝/绿部署执行主要版本升级

从历史上看,您可以通过以下几种方式进行主要版本升级:

  • 就地升级 -这涉及一个简单且一键管理的工作流程。升级通常需要大约 10—15 分钟,但可能因数据库对象(表、架构、序列等)的数量而异。
  • 手动创建暂存环境 -使用 本机逻辑复制 亚马逊云科技 Database Migration Ser vice (亚马逊云科技 DMS) 手动创建暂存环境可以提供更高的控制程度和更低的停机时间,但代价是大量的规划和协调。

有关这些选项的更多信息,请参阅 升级适用于 PostgreSQL 的亚马逊 RDS 或亚马逊 Aurora PostgreSQL 数据库,第 1 部分: 比较升级方法。

通过蓝/绿部署,现在您可以通过一种简单且完全托管的方式来执行主要版本升级。作为部署的一部分,您可以在新的主要版本上创建绿色集群,也可以在绿色集群准备就绪后使用就地升级手动升级绿色集群。有关在绿色集群上执行就地升级的信息,请参阅以下适用 于 PostgreSQL 的 亚马逊 RDS 亚马逊 Aurora PostgreSQL 的指南。

如果要在部署过程中自动升级绿色集群,则必须使用其他参数,例如--target-eng ine-version 和 --target-db-parameter-g roup-name,如以下 示例代码所示。确保使用未来生产集群所需的自定义设置创建一个名为 pg15-blu e-green 的新参数组。

aws rds create-blue-green-deployment \
--blue-green-deployment-name my-blue-green-deployment \
--source arn:aws:rds:{REGION}:{ACCOUT_ID}:db:blue-green-inst01 \
--target-engine-version 15.3 \
--target-db-parameter-group-name pg15-blue-green

下图显示了执行主要版本升级的高级步骤。

工作流程步骤如下:

  1. 现有的生产集群充当当前的蓝色主集群。
  2. 创建蓝/绿部署时,它会将当前生产环境(蓝色)的镜像副本创建为绿色群集,这将是未来的生产环境。
  3. Amazon RDS 在绿色集群上执行主要版本升级。在绿色群集上运行就地主版本升级时,不会对蓝色群集产生任何影响。在升级绿色环境时,复制会落后,但在主要版本升级完成后它会迎头赶上。
  4. 然后,绿色集群被提升为新的主集群。

执行切换

升级绿色群集且复制完全同步后,您可以切换到绿色群集(新的生产集群)。Amazon RDS 会执行多项检查,这些检查充当护栏以确保安全切换:

  • 例如检查健康状况
  • 检查以验证蓝群集和绿色群集之间的复制是否已同步
  • 检查是否在蓝色群集上执行了任何 DDL 活动(这将阻止您切换)
  • 检查是否有 大型物体 (这将阻止你切换)
  • 确保蓝色群集上没有长时间运行的活动写入或长时间运行的 DDL
  • 确保蓝色的主数据库实例不是外部复制的目标,以防止在切换期间写入蓝色的主数据库实例

所有检查通过后,Amazon RDS 将在切换过程中执行以下操作:

  1. Amazon RDS 停止对蓝色和绿色集群的写入,并断开来自这两个集群的连接。
  2. 在从蓝色群集切换到绿色群集之前,Amazon RDS 确保绿色群集与蓝色群集完全同步。
  3. Amazon RDS 增加绿色环境中的序列值以匹配蓝色环境中的序列值。
  4. 绿色集群被提升为新的主集群。
  5. Amazon RDS 重命名绿色环境中的数据库实例,以匹配蓝色环境中的相应数据库实例。同时,亚马逊 RDS 使用后缀 -old { n} 重命名蓝色集群。 例如,如果您的旧集群名为 mydb ,则绿色集群将命名为 mydb,而旧的蓝色数据库将命 名为 mydb -old1。

接下来,我们使用绿色集群(新的主集群)打开与两个集群的连接,该群集开始接受写入。蓝色集群(旧的主集群)将在重启之前提供只读查询,以避免出现脑分裂的情况。

以下是执行切换的示例命令:

aws rds switchover-blue-green-deployment 
--blue-green-deployment-identifier my-blue-green-deployment 
--switchover-timeout 60

如果切换所需的时间超过指定的切 换超时 ,则会回滚所有更改 ,并且不会对任何环境进行任何更改。

最佳实践

在本节中,我们将讨论使用蓝/绿部署的最佳实践,以及在蓝/绿部署中构建的客户体验来管理 PostgreSQL 逻辑复制 的当前 限制

对主键的要求

PostgreSQL 逻辑复制,蓝/绿部署根据表数据的复制身份(通常是主键)复制表数据。如果您有任何没有主键的表,则表上的任何插入内容都将被复制。但是,以下消息将阻止对该表的更新和删除:

ERROR: cannot update table "without_pkey" because it does not have a replica identity and publishes updates

HINT: To enable updating the table, set REPLICA IDENTITY using ALTER TABLE.

确保每个表都有复制标识,例如主键或唯一键,这一点很重要。

例如,假设你有一个没有主键的表:

\d sample
               Table "public.sample"
 Column |  Type   | Collation | Nullable | Default
--------+---------+-----------+----------+---------
 a      | integer |           |          |
 b      | integer |           |          |
 c      | integer |           |          |

你有几个选择。第一个选项是创建唯一索引并使用唯一索引作为复制标识,或者使用 REPLICA IDENTITY FULL 。以下是使用 UNIQUE 索引作为复制标识的示例:

ALTER TABLE sample ALTER COLUMN c SET NOT NULL;
CREATE unique INDEX index_c on sample(c);
ALTER TABLE sample REPLICA IDENTITY USING INDEX index_c;

                                  Table "public.sample"
 Column |  Type   | Collation | Nullable | Default | Storage | Stats target | Description
--------+---------+-----------+----------+---------+---------+--------------+-------------
 a      | integer |           |          |         | plain   |              |
 b      | integer |           |          |         | plain   |              |
 c      | integer |           | not null |         | plain   |              |
Indexes:
    "index_c" UNIQUE, btree (c) REPLICA IDENTITY

以下是使用 REPLICA IDENTITY FULL 的示例:

ALTER TABLE sample REPLICA IDENTITY FULL;  
  
                              Table "public.sample"
 Column |  Type   | Collation | Nullable | Default | Storage | Stats target | Description
--------+---------+-----------+----------+---------+---------+--------------+-------------
 a      | integer |           |          |         | plain   |              |
 b      | integer |           |          |         | plain   |              |
 c      | integer |           |          |         | plain   |              |
Publications:
    "mypub"
Replica Identity: FULL

在 REPLICA IDENTITY FULL 的情况下,所有列值都写入预写日志 (WAL)。因为它增加了 WAL 的详细程度,因此会消耗资源,因此不建议将其用于大量更新的表。

对于蓝/绿部署,在创建绿色集群之前,确保所有表都有复制标识非常重要。在发布此功能时,在引导绿色集群后,您将无法对蓝/绿数据库进行任何 DDL 更改。

处理架构更改 (DDL)

根据 PostgreSQL 逻辑复制 的当前 限制 ,我们不支持在绿色集群上进行架构更改(“数据定义语言” 或 “DDL”)或复制 DDL 更改。但是,可以在蓝色群集上应用架构更改,但这会导致以下消息:

postgres=*> create table sample (id serial);
WARNING: command will not be replicated to the green instance: "CREATE TABLE"
CREATE TABLE

在内部,我们会跟踪应用于蓝色群集的任何 DDL 更改。任何 DDL 活动都将记录在 PostgreSQL 日志中并生成 RDS 事件通知。 Amazon RDS 控制台会将复制状态报告为 “复制已降级”。此时,您可以立即采取措施删除或重新创建蓝/绿部署。在切换操作期间,如果在蓝色集群上执行任何 DDL 活动,Amazon RDS 将执行检查并防止切换到绿色集群。该护栏可确保数据一致性并防止任何数据丢失。

值得注意的是,即使你创建了一个表然后将其删除,它仍会被标记为 DDL 活动,并阻止你切换到绿色集群。在这种情况下,建议创建一个新的绿色集群。

在创建绿色群集后,您可以通过以下两种方式检查是否在蓝色群集上执行了任何 DDL 活动:

  • 使用 rds_tools 扩展名 :po stgres => 创建扩展名
    rds_tools;创建扩展名 postgres=> 从 rds_tools.blue_get_status('ddl')中选择 *;file_exists — t(1
    行)

如果 file_ex ists 为 t ,则 表示检测到了 DDL 活动。

  • 在 Amazon RDS 控制台 上的 “ 日志和事件 ” 下查看最近发生的事件。您预计会看到与以下内容类似的事件:
Data definition language (DDL) changes aren't supported for blue/green deployments. These changes aren't replicated from the blue environment to the green environment, and switchover will be blocked. Your green databases now have a status of REPLICATION_DEGRADED

处理大量的数据库和表

如前所述,蓝/绿部署基于逻辑复制。逻辑复制使用发布和订阅模式,其中一个或多个订阅者在发布者节点上订阅一个或多个出版物。在一个 RDS 集群中,您可以创建多个数据库。PostgreSQL 中的逻辑复制是基于每个数据库完成的,这意味着每个数据库至少会有一个发布和订阅。

随着数据库数量的增加,将有更多的发布和订阅以及相同数量的逻辑复制槽。对于存在的每增加一个数据库,蓝色群集上的 CPU 和内存资源消耗就会更高,这可能会影响当前生产群集的性能(蓝色)。

以下是一些关键参数和建议:

  • max_replication_slot s — 必须将其设置为至少要连接的订阅数量,外加一些用于表同步的预留空间。每个数据库将有一个订阅,因此请务必设置一个大于数据库数量的数字。
  • max_wal_send er — 这是系统可以支持的最大后台进程数。建议将此数字设置为略高于 max_replication_slots
  • max_logical_replication_worker — 您应该将其设置为多个数据库,并为表同步工作程序和并行应用工作线程预留一些资源。
  • max_worker_p rocesses — 这是系统可以支持的最大后台进程数。应将其设置为最小值 max_logical_replication_worker + 1 或更高。

在创建绿色集群之前,Amazon RDS 将检查这些值作为先决条件。如果设置不兼容,它将无法创建绿色集群。

如果数据库中有大量表,则复制和同步的时间将根据 max_logical_replication_worker 设置和表的大小而增加。

内存调节

在逻辑复制中, walsend er 进程负责在提交事务时解码来自 WAL 的更改。在 PostgreSQL 版本 12 及更低版本中,PostgreSQL 维护一个内存哈希表来跟踪更改。对于每笔交易,当内存的最大更改超过 4096 个时,其余更改将溢出到磁盘。需要将其读回以进一步处理事务,这会减慢复制速度。如果您使用的是 PostgreSQL 13 或更高版本,建议在将一些 解码后的更改写入磁盘之前,先调整 logical_decoding_work_mem ,这是逻辑解码使用的最大内存量。将此值设置为更高将确保逻辑解码不必溢出到磁盘并回读即可解码。在增加此值之前,请确保有足够的可用内存。 你可以使用 FreeableMemory Amazon CloudWatch 指标 监控可用内存。 有关更多信息,请参阅 亚马逊 RDS 的亚马逊 CloudWatch 实例级指标

序列

由于序列不是通过逻辑复制来复制的,因此在切换期间需要在蓝群集和绿色群集之间同步序列。作为切换过程的一部分,这种同步序列的操作由 Amazon RDS 自动处理。

由于此操作是在切换过程中执行的,因此如果您有大量序列,则可能会增加切换过程的时间。

大型物体

逻辑复制不支持大型对象( pg_largeobject )。如果蓝色群集上有大型对象,则切换后该数据在绿色群集上将不可用,从而导致数据丢失。建议您的应用程序使用其他存储机制,例如字节类型或 亚马逊简单存储服务 (Amazon S3) 来存储大型对象。

物化视图

物化视图用于物理存储数据,可以通过 REFRESH MATERIALIZED VIEW 命令进行更新。绿色群集上实例化视图的数据可能与蓝色群集上的数据不匹配。但是,您可以在绿色群集上运行 REFRESH MATERIALIZED VIEW 来更新实例化视图以反映最新数据。

国外桌子

如果您在蓝色群集上配置了任何外部表,则不会在绿色群集上配置这些表。在这种情况下,在切换之前,您必须在绿色群集上手动配置外部表。

扩展

在创建蓝/绿部署之前,请务必将所有 PostgreSQL 扩展程序更新到最新版本,以便它们可以与更高的主要版本(绿色集群)兼容。

如果你使用的是 pg_partman pg_cron 或 QPM 扩展名 ,它正在数据库上 运行 DML 活动,请务必在绿色集群上将其禁用。对于 aws_s3 扩展,请确保在创建绿色环境后通过 亚马逊云科技 身份和访问管理 (IAM) 角色向绿色数据库实例授予访问 Amazon S3 的权限。这允许导入和导出命令在切换后继续运行。有关说明,请参阅 设置对 Amazon S3 存储桶的访问权限 。如果您启用了具有持续外部复制功能的 p glo gic 或 pgactiv e 扩展,我们建议您在创建蓝/ 绿部署之前将其禁用。

清理

如果你在这篇文章中为适用于 PostgreSQL 的亚马逊 RDS 或 Amazon Aurora PostgreSQL 集群创建了蓝/绿部署但不再需要使用它们,那么此时你可以将其删除。

要删除蓝/绿部署,必须先获取 BluegreenDeploymentIdentifier。 例如,要从前面的示例中获取蓝/绿标识符,可以运行以下命令:

aws cli describe-blue-green-deployments --filter Name=blue-green-deployment-name,Values=my-blue-green-deployment  |  jq -r '.BlueGreenDeployments[].BlueGreenDeploymentIdentifier'
bgd-hbdx33wp6lx6secr

接下来,使用以下 CLI 命令在绿色环境中删除蓝/绿部署和数据库集群。使用前面命令中的部署标识符。

aws rds delete-blue-green-deployment \
    --blue-green-deployment-identifier bgd-hbdx33wp6lx6secr \
    --delete-target

有关使用 亚马逊云科技 管理控制台删除蓝/绿部署的更多选项和说明 ,请参阅文档

结论

Amazon RDS 蓝/绿部署将生产数据库环境复制到单独的同步暂存环境中。通过蓝/绿部署,您可以在不影响生产环境的情况下更改暂存环境中的数据库。例如,您可以升级主要或次要的数据库引擎版本并更改数据库参数。准备就绪后,可以将暂存环境升级为新的生产数据库环境,停机时间通常不到一分钟。

请访问 Amazon RDS 功能页面 并使用我们的 技术 文档,了解有关蓝/绿部署的更多信息。 使用 Amazon RDS 控制台 或 Amazon RDS API 为您的数据库创建蓝/绿部署,以更新您的生产数据库。


作者简介

Chirag Dave 是亚马逊网络服务的首席解决方案架构师,专注于托管 PostgreSQL。他与客户保持技术关系,就安全性、成本、性能、可靠性、运营效率和最佳实践架构提出建议。


*前述特定亚马逊云科技生成式人工智能相关的服务仅在亚马逊云科技海外区域可用,亚马逊云科技中国仅为帮助您发展海外业务和/或了解行业前沿技术选择推荐该服务。