使用 Amazon RDS Proxy(预览版)管理连接 - Amazon Relational Database Service
AWS 文档中描述的 AWS 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅中国的 AWS 服务入门

使用 Amazon RDS Proxy(预览版)管理连接

这是 Amazon RDS 代理的预览版文档。本文档随时可能更改。

使用 Amazon RDS Proxy,您可以允许应用程序对数据库连接进行池化和共享以提高可扩展性。RDS Proxy 通过自动连接到备用数据库实例,同时保留应用程序连接,使应用程序能够更灵活地应对数据库故障。RDS Proxy 还允许您对数据库强制执行 AWS Identity and Access Management (IAM) 身份验证,以及在 AWS Secrets Manager 中安全存储凭证。

注意

RDS Proxy 与 MySQL 和 PostgreSQL 完全兼容。您可以在不更改代码的情况下为大多数应用程序启用 RDS Proxy。

使用 RDS Proxy,您可以处理不可预测的数据库流量激增,这种情况可能由于超额预订连接或快速创建新连接而导致问题。RDS Proxy 建立数据库连接池,并重复使用该池中的连接,而不会因为每次打开新数据库连接而产生内存和 CPU 开销。要防止数据库超额订阅,您可以控制创建的数据库连接数。

RDS Proxy 对无法立即从连接池提供服务的应用程序连接进行排队或限制。尽管延迟可能会增加,但您的应用程序可以继续扩展,而不会导致数据库突然出现故障或不堪重负。如果连接请求超出您指定的限制,则 RDS Proxy 拒绝应用程序连接(减轻负载)。与此同时,它为通过可用容量提供服务的负载维护可预测的性能。

您可以减少处理凭证的开销,并为每个新连接建立安全连接。RDS Proxy 可以代表数据库处理其中的一些工作。

重要

目前,Amazon RDS Proxy 还是预览版。不要将 RDS Proxy 用于生产工作负载。另外,我们强烈建议不要将敏感数据放入用于 RDS Proxy 预览版的数据库中。在预览期间,您可能会遇到导致结果错误和/或数据损坏的问题。在预览期间,我们可能会引入重大更改,恕不另行通知。这些可能包括 API 操作的升级和更改。

RDS Proxy 概念和术语

这是 Amazon RDS 代理的预览版文档。本文档随时可能更改。

您可以通过使用 RDS Proxy 来简化 Amazon RDS 数据库实例和 Aurora 数据库集群的连接管理。

RDS Proxy 处理客户端应用程序和数据库之间的网络流量。为实现这一点,它首先了解数据库协议。然后,它根据应用程序中的 SQL 操作和数据库中的结果集来调整其行为。RDS Proxy 可减少数据库连接管理的内存和 CPU 开销。当应用程序打开多个同时连接时,数据库所需的内存和 CPU 资源较少。而且也不需要应用程序中的逻辑来关闭和重新打开长时间处于空闲状态的连接。同样,在出现数据库问题时,需要较少的应用程序逻辑来重新建立连接。

RDS Proxy 的基础设施独立于 RDS 数据库实例和 Aurora 数据库集群的数据库服务器。这种分离有助于减少数据库服务器的开销,使它们能够将资源用于处理数据库工作负载。

RDS Proxy 术语概述

RDS Proxy 处理基础设施以执行连接池和本文档中描述的其他功能。您可以在 Proxies (代理) 页面上看到用于 RDS 的 AWS 管理控制台中表示的代理。

每个代理处理与单个 RDS 数据库实例或 Aurora 数据库集群的连接。对于 RDS 多可用区数据库实例和 Aurora 预配置集群,代理将确定当前写入器实例。

代理保持打开状态且可供数据库应用程序用于形成连接池的连接。

默认情况下,RDS Proxy 可在会话中的每个事务之后重用连接。这种事务级别的重用称为多路复用。在某些情况下,RDS Proxy 无法确定从会话使用不同连接运行不同事务是否安全。在这些情况下,它将会话保持在同一个连接上,直到会话结束。此回退行为称为固定

代理有一个终端节点。使用 RDS 数据库实例或 Aurora 数据库集群时,您将连接到该终端节点,而不是连接到直接连至实例或集群的读写终端节点。Aurora 集群的专用终端节点仍可供您使用。例如,您仍可连接到集群终端节点以实现读写连接,而无需连接池。您仍可连接到读取器终端节点以实现负载均衡的只读连接。您仍可连接到实例终端节点,以便对 Aurora 集群中的特定数据库实例进行诊断和故障排除。如果您要使用其他 AWS 服务(例如 AWS Lambda)连接到 RDS 数据库,则需要将其连接设置更改为使用代理终端节点。例如,指定代理终端节点,以允许 Lambda 函数在利用 RDS Proxy 功能的同时访问数据库。

每个代理都包含一个目标组。该目标组包含代理可连接到的 RDS 数据库实例或 Aurora 数据库集群。对于 Aurora 集群,默认情况下,目标组与该集群中的所有数据库实例相关联。这样,代理就可以连接到被提升为集群中的写入器实例的任何 Aurora 数据库实例。与代理关联的 RDS 数据库实例或 Aurora 数据库集群及其实例称为该代理的目标。为方便起见,当您通过 AWS 管理控制台 创建代理时,RDS Proxy 也会创建相应的目标组并自动注册关联的目标。

引擎系列是使用相同数据库协议的相关数据库引擎集。您可以为创建的每个代理选择引擎系列。对于全局数据库,您可以为主 AWS 区域创建代理,但不能为只读辅助 AWS 区域创建代理。

连接池

每个代理都为其关联的 RDS 或 Aurora 数据库的写入器实例执行连接池。连接池 是一项优化,可减少与打开和关闭连接相关的开销,并可保持许多连接同时打开。该开销包括处理每个新连接所需的内存。此外还包括关闭每个连接和打开新连接所产生的 CPU 开销,例如传输层安全性/安全套接字层 (TLS/SSL) 握手、身份验证、协商功能等。连接池可简化应用程序逻辑。无需编写应用程序代码,即可最大限度地减少同时打开的连接数量。

每个代理还执行连接多路复用,也称为连接重用。对于多路复用,RDS Proxy 使用一个底层数据库连接对事务执行所有操作,然后可以对下一个事务使用不同的连接。您可以同时打开许多到代理的连接,而代理可确保打开的到数据库实例或集群的连接数量较少。这样做可进一步减少数据库服务器上连接的内存开销。这项技术还降低了出现“连接过多”错误的可能性。

RDS Proxy 安全性

RDS Proxy 使用现有的 RDS 安全机制,如传输层安全/安全套接字层 (TLS/SSL) 和 AWS Identity and Access Management (IAM)。有关这些安全功能的一般信息,请参阅 Amazon RDS 中的安全性。如果您不熟悉 RDS 和 Aurora 如何处理身份验证、授权和其他安全领域,请先查阅这些资源。

RDS Proxy 可作为客户端应用程序和底层数据库之间的附加安全层。例如,即使底层数据库实例仅支持 TLS 1.0 或 1.1,您也可以使用 TLS 1.2 连接到代理。即使代理使用本机用户/密码身份验证方法连接到数据库,您也可以使用 IAM 角色连接到代理。通过采用这项技术,您可以对数据库应用程序强制执行强身份验证要求,而无需对数据库实例本身进行成本高昂的迁移。

您将 RDS Proxy 使用的数据库凭证存储在 AWS Secrets Manager 中。代理访问的 RDS 数据库实例或 Aurora 数据库集群的每个数据库用户都必须在 Secrets Manager 中拥有相应的密钥。您还可为 RDS Proxy 的用户设置 IAM 身份验证。这样一来,即使数据库仍使用本机密码身份验证,您也可以对数据库访问强制执行 IAM 身份验证。与在应用程序代码中嵌入数据库凭证相比,这些安全功能是更好的替代方法。

将 TLS/SSL 与 RDS Proxy 结合使用

您可以使用 TLS/SSL 协议连接到 RDS Proxy。

注意

RDS Proxy 使用来自 AWS Certificate Manager (ACM) 的证书。如果您正在使用 RDS Proxy,当您轮换 TLS/SSL 证书时,您不需要更新使用 RDS Proxy 连接的应用程序。

RDS Proxy 可确保您的会话在客户端与 RDS Proxy 终端节点之间使用 TLS/SSL。要让 RDS Proxy 这样做,请使用 --ssl-mode 参数在客户端上指定此要求。没有为 RDS Proxy 数据库的 SSL 连接设置 SSL 会话变量。

RDS Proxy 支持 TLS 协议版本 1.0、1.1 和 1.2。不过,您无需为 TLS 配置 RDS Proxy 数据库。特别是,不要对 SSL 的数据库用户权限使用 REQUIRE 子句。这样做会阻止该用户进行连接。

默认情况下,客户端程序会与 RDS Proxy 建立加密连接,并通过 --ssl-mode 选项进行进一步控制。从服务器端,RDS Proxy 支持所有 SSL 模式。

对于客户端,SSL 模式如下:

PREFERRED

SSL 是首选项,但不是必需项。

DISABLED

不允许使用 SSL。

REQUIRED

强制 SSL。

VERIFY_CA

强制 SSL 并验证证书颁发机构 (CA)。

VERIFY_IDENTITY

强制 SSL 并验证 CA 和 CA 主机名。

将客户端与 --ssl-modeVERIFY_CAVERIFY_IDENTITY 结合使用时,以 .pem 格式指定指向 CA 的 --ssl-ca 选项。对于可使用的 .pem 文件,您可以从 Amazon Trust Services 下载 Amazon Root CA 1 信任存储

RDS Proxy 使用通配符证书,这些证书应用到域及其子域。如果您使用 mysql 客户端以 SSL 模式 VERIFY_IDENTITY 进行连接,则您当前必须使用与 MySQL 8.0 兼容的 mysql 命令。

故障转移

故障转移是一项高可用性功能,可在原始实例变得不可用时将数据库实例替换为另一个数据库实例。可能会因为数据库实例出现问题而发生故障转移。故障转移也可能是正常维护程序的一部分,例如在数据库升级期间。故障转移适用于多可用区配置中的 RDS 数据库实例,以及除写入器实例外还具有一个或多个读取器实例的 Aurora 数据库集群。

通过代理进行连接可使您的应用程序对数据库故障转移更具弹性。当原始数据库实例变得不可用时,RDS Proxy 将连接到备用数据库,而不删除空闲应用程序连接。这样做有助于加快和简化故障转移过程。结果,故障转移速度更快,与典型的重启或数据库问题相比,对应用程序造成的干扰更小。

如果没有 RDS Proxy,故障转移会导致短暂中断。在中断期间,您无法对该数据库执行写入操作。任何现有数据库连接都会中断,您的应用程序必须重新打开这些连接。当一个只读数据库实例被提升为取代不可用的数据库实例时,数据库将可用于新连接和写入操作。

在数据库故障转移期间,RDS Proxy 将继续接受相同 IP 地址的连接,并自动将连接定向到新的主数据库。通过 RDS Proxy 连接的客户端不会受到以下情况的影响:

  • 故障转移时的 DNS 传播延迟。

  • 本地 DNS 缓存。

  • 连接超时。

  • 不确定哪个数据库实例是当前的写入器。

  • 等待来自以前写入器的查询响应,该写入器在未关闭连接的情况下变得不可用。

对于维护自身连接池的应用程序,完成 RDS Proxy 意味着大多数连接在故障转移或其他中断期间保持活动状态。只有处于事务或 SQL 语句中间的连接才会被取消。RDS Proxy 会立即接受新连接。当数据库写入器不可用时,RDS Proxy 将对传入的请求进行排队。

对于不维护自身连接池的应用程序,RDS Proxy 提供更快的连接速度和更多的打开连接。它减轻了频繁从数据库重新连接而产生的昂贵开销。这是通过重用 RDS Proxy 连接池中维护的数据库连接来实现。此方法对于 TLS 连接尤其重要,因为这些连接的设置成本很高。

事务

单个事务中的所有语句始终使用相同的底层数据库连接。当事务结束时,连接可供另一会话使用。使用事务作为粒度单位会产生以下后果:

  • 启用 autocommit 设置后,每个单独的语句之后都会发生连接重用。

  • 相反,禁用 autocommit 设置后,您在会话中发出的第一个语句会启动新的事务。因此,如果您输入 SELECTINSERTUPDATE 和其他数据操作语言 (DML) 语句的序列,则在您发出 COMMITROLLBACK 或以其他方式结束事务之前不会发生连接重用。

  • 输入数据定义语言 (DDL) 语句会导致事务在该语句完成后结束。

RDS Proxy 通过数据库客户端应用程序使用的网络协议检测事务何时结束。事务检测不依赖于关键字,例如 SQL 语句文本中显示的 COMMITROLLBACK

在某些情况下,RDS Proxy 可能会检测到使得无法将会话移动到其他连接的数据库请求。在这些情况下,它会在会话的剩余时间关闭该连接的多路复用。当 RDS Proxy 不能确定多路复用是否适用于会话时,这一规则也适用。该操作称为固定。有关检测和最小化固定的方法,请参阅 避免固定

规划和设置 RDS Proxy

这是 Amazon RDS 代理的预览版文档。本文档随时可能更改。

在以下部分中,您可以了解如何设置 RDS Proxy。您还可以了解如何设置相关的安全性选项,以控制哪些人可以访问各个代理,以及各个代理如何连接到数据库实例。

RDS Proxy 的限制

这是 Amazon RDS 代理的预览版文档。本文档随时可能更改。

以下限制适用于公开预览版期间的 RDS Proxy:

  • 公开预览版仅在以下 AWS 区域可用:

    • 美国东部(弗吉尼亚北部)地区

    • 美国东部(俄亥俄)区域

    • 美国西部(加利福利亚北部)区域

    • 美国西部(俄勒冈)区域

    • 亚太地区(孟买)区域

    • 亚太区域(首尔)

    • 亚太区域(新加坡)

    • 亚太区域(悉尼)

    • 亚太区域(东京)

    • 加拿大 (中部) 区域

    • 欧洲(法兰克福)区域

    • 欧洲(爱尔兰)区域

    • 欧洲(伦敦)区域

  • 每个 AWS 账户 ID 最多可拥有 20 个代理。

  • 每个代理最多可拥有 200 个关联的 Secrets Manager 密钥。因此,每个代理可以在任何给定时间连接多达 200 个不同的用户账户。

  • 在 Aurora 集群中,连接池中的所有连接都由 Aurora 写入器实例处理。要对读取密集型工作负载执行负载均衡,仍然需要直接对 Aurora 集群使用读取器终端节点。

  • 不能将 RDS Proxy 与 Aurora Serverless 集群一起使用。

  • 不能将 RDS Proxy 与 Aurora 多主集群一起使用。

  • 您的 RDS Proxy 必须与数据库位于同一 VPC 中。代理无法公开访问,但数据库可以。

  • 您不能将代理与自定义 DNS 一起使用。

  • RDS Proxy 可用于 MySQL 和 PostgreSQL 引擎系列。

以下 RDS Proxy 限制适用于 MySQL:

  • MySQL 引擎系列包括 RDS MySQL 5.6 和 5.7 以及 Aurora MySQL 版本 1 和 2。

  • 目前,所有代理均在端口 3306 上侦听 MySQL。

  • 在 MySQL 引擎系列中,RDS Proxy 当前支持 Aurora 预置集群、Aurora 并行查询集群和 Aurora 全局数据库。

  • 不能将 RDS Proxy 与 RDS MySQL 8.0 一起使用。

  • 不能将 RDS Proxy 与 EC2 实例中自行管理的 MySQL 数据库一起使用。

  • 代理不支持 MySQL 压缩模式。例如,它们不支持 mysql 命令的 --compress-C 选项使用的压缩。

  • 并不会实现所有逻辑,以将会话固定到基于 SQL 语句和函数的数据库连接。有关最新的固定行为,请参阅 避免固定

以下 RDS Proxy 限制适用于 PostgreSQL:

  • RDS PostgreSQL 引擎系列包括版本 10.10 和更高的次要版本,以及版本 11.5 和更高的次要版本。

  • 目前,所有代理均在端口 5432 上侦听 PostgreSQL。

  • PostgreSQL 不支持查询取消。

  • PostgreSQL 函数的 lastval() 结果并不总是准确的。作为解决方法,请将 INSERT 语句与 RETURNING 子句一起使用。

识别要用于 RDS Proxy 的数据库实例、集群和应用程序

您可以确定哪些数据库实例、集群和应用程序可能从使用 RDS Proxy 中受益匪浅。为此,请考虑以下因素:

  • RDS Proxy 高度可用,部署在多个可用区 (AZ) 上。要确保数据库的总体高可用性,请在多可用区配置中部署 Amazon RDS 数据库实例或 Aurora 集群。

  • 任何曾出现“连接过多”错误的数据库实例或集群都很适合与代理相关联。代理允许应用程序打开许多客户端连接,而代理管理与数据库实例或集群的少量长期连接。

  • 对于使用较小 AWS 实例类(如 T2 或 T3)的数据库实例或集群,使用代理可以帮助避免内存不足情况。它还可以帮助减少建立连接时的 CPU 开销。处理大量连接时可能会发生这些情况。

  • 您可以监控某些 Amazon CloudWatch 指标,以确定数据库实例或集群是否接近某些类型的限制。这些限制针对连接数以及与连接管理关联的内存。您还可以监控某些 CloudWatch 指标,以确定数据库实例或集群是否处理许多短期连接。打开和关闭此类连接可能会给数据库带来性能开销。有关要监控的指标的信息,请参阅 使用 Amazon CloudWatch 监控 RDS Proxy

  • AWS Lambda 函数也可以很好地使用代理。这些函数进行频繁的短数据库连接,可受益于 RDS Proxy 提供的连接池。您可以利用已为 Lambda 函数提供的任何 IAM 身份验证,而不是在 Lambda 应用程序代码中管理数据库凭证。

  • 使用 PHP 和 Ruby on Rails 等语言和框架的应用程序通常可以很好地使用代理。此类应用程序通常打开和关闭大量数据库连接,并且没有内置的连接池机制。

  • 长时间保持大量连接打开的应用程序通常可以很好地使用代理。诸如软件即服务 (SaaS) 或电子商务等行业中的应用程序通常会使连接保持打开状态,从而最大限度地减少数据库请求的延迟。

  • 由于为所有数据库实例和集群设置此类身份验证较为复杂,您可能尚未采用 IAM 身份验证和 Secrets Manager。如果是这样,您可以保留现有的身份验证方法,并将身份验证委派给代理。代理可以为特定应用程序的客户端连接强制执行身份验证策略。您可以利用已为 Lambda 函数提供的任何 IAM 身份验证,而不是在 Lambda 应用程序代码中管理数据库凭证。

设置网络先决条件

使用 RDS Proxy 要求您拥有一组联网资源。这些资源包括 Virtual Private Cloud (VPC)、两个或更多子网、相同 VPC 内的 Amazon EC2 实例和一个互联网网关。如果已成功连接到任何 RDS 数据库实例或 Aurora 数据库集群,则您已拥有所需的网络资源。

在 AWS Secrets Manager 中设置数据库凭证

对于您创建的每个代理,首先使用 Secrets Manager 服务来存储用户名和密码凭证集。您可以在 RDS 数据库实例或 Aurora 数据库集群上,为代理连接到的每个数据库用户账户分别创建 Secrets Manager 密钥。

在 Secrets Manager 中,您可以使用 usernamepassword 字段创建这些密钥。这样一来,代理可以连接到与代理关联的任何 RDS 数据库实例或 Aurora 数据库集群上的相应数据库用户。为此,您可以使用 Credentials for other database (其他数据库的凭证)Credentials for RDS database (RDS 数据库凭证)Other type of secrets (其他密钥类型) 设置。

代理会忽略其他存在于密钥中的字段,如 hostport。这些详细信息由代理自动提供。如果选择 Credentials for other database (其他数据库的凭证),则该选项将提示您输入用户名和密码,而不输入您在代理自身设置中指定的其他连接详细信息。如果选择 Other type of secrets (其他密钥类型),则使用名为 usernamepassword 的密钥创建密钥。

不要为密钥选择任何轮换周期。

由于密钥不与特定数据库服务器绑定,因此,如果在多个数据库服务器上使用相同的凭证,则可对多个代理重用一个密钥。例如,您可以在一组开发和测试服务器上使用相同的凭证。

如果与密钥关联的密码不正确,您可以在 Secrets Manager 中更新关联的密钥。例如,如果数据库账户的密码更改,您可以更新密钥。更新密钥之前,无法通过代理连接到该数据库账户。您仍可连接到密码与密钥中存储的凭证匹配的其他账户。

通过 AWS CLI 或 RDS API 创建代理时,请为代理可访问的所有数据库用户账户指定相应密钥的 Amazon 资源名称 (ARN)。在 AWS 管理控制台 中,根据描述性名称选择密钥。

有关在 Secrets Manager 中创建密钥的说明,请参阅 Secrets Manager 文档中的创建密钥页面。使用下面的方法之一。有关在 Secrets Manager 中创建密钥的说明,请参阅 AWS Secrets Manager 用户指南 中的创建密钥。使用下面的方法之一:

  • 使用控制台中的 Secrets Manager

  • 要使用 CLI 创建与RDS Proxy 一起使用的 Secrets Manager 密钥,请使用类似如下的命令。

    aws secretsmanager create-secret --name "secret_name" --description "secret_description" --region region_name --secret-string '{"username":"db_user","password":"db_user_password"}'

例如,以下命令为两个数据库用户(一个名为 admin,另一个名为 app-user)创建 Secrets Manager 密钥。

aws secretsmanager create-secret \ --name $ADMIN_SECRET --description "db admin user" \ --secret-string '{"username":"admin","password":"choose_your_own_password"}' aws secretsmanager create-secret \ --name $PROXY_SECRET --description "application user" \ --secret-string '{"username":"app-user","password":"choose_your_own_password"}'

设置 AWS Identity and Access Management (IAM) 策略

在 Secrets Manager 中创建密钥后,请创建一个可以访问这些密钥的 IAM 策略。

  • 请遵循创建角色流程。包括 Add Role to Database (将角色添加到数据库) 步骤。

  • 对于新角色,请执行添加内联策略步骤。粘贴以下 JSON,用 Amazon 资源名称 (ARN) 替换您创建的密钥。

    { "Version": "2012-10-17", "Statement": [ { "Sid": "VisualEditor0", "Effect": "Allow", "Action": [ "secretsmanager:GetRandomPassword", "secretsmanager:CreateSecret", "secretsmanager:ListSecrets" ], "Resource": "*" }, { "Sid": "VisualEditor1", "Effect": "Allow", "Action": "secretsmanager:*", "Resource": [ "your_secret_ARN" ] } ] }
  • 或者,编辑此 IAM 策略的信任策略。粘贴以下 JSON。

    { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "Service": "rds.amazonaws.com" }, "Action": "sts:AssumeRole" }, { "Sid": "", "Effect": "Allow", "Principal": { "Service": "rds.amazonaws.com" }, "Action": "sts:AssumeRole" } ] }

以下命令通过 AWS CLI 执行相同的操作。

PREFIX=choose_an_identifier aws iam create-role --role-name choose_role_name \ --assume-role-policy-document '{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Principal":{"Service":["rds.amazonaws.com"]},"Action":"sts:AssumeRole"}]}' aws iam put-role-policy --role-name same_role_name_as_previous \ --policy-name $PREFIX-secret-reader-policy --policy-document '{"Version":"2012-10-17","Statement":[{"Sid":"getsecretvalue","Effect":"Allow","Action":["secretsmanager:GetSecretValue","kms:Decrypt"],"Resource":"*"}]}' aws kms create-key --description "$PREFIX-test-key" --policy '{"Id":"$PREFIX-kms-policy","Version":"2012-10-17","Statement":[{"Sid":"Enable IAM User Permissions","Effect":"Allow","Principal":{"AWS":"arn:aws:iam::account_id:root"},"Action":"kms:*","Resource":"*"},{"Sid":"Allow access for Key Administrators","Effect":"Allow","Principal":{"AWS":["$USER_ARN","arn:aws:iam::account_id:role/Admin"]},"Action":["kms:Create*","kms:Describe*","kms:Enable*","kms:List*","kms:Put*","kms:Update*","kms:Revoke*","kms:Disable*","kms:Get*","kms:Delete*","kms:TagResource","kms:UntagResource","kms:ScheduleKeyDeletion","kms:CancelKeyDeletion"],"Resource":"*"},{"Sid":"Allow use of the key","Effect":"Allow","Principal":{"AWS":"$ROLE_ARN"},"Action":["kms:Decrypt","kms:DescribeKey"],"Resource":"*"}]}'

创建 RDS Proxy

要管理指定数据库实例集的连接,您可以创建代理。您可以将代理与 RDS MySQL 数据库实例、PostgreSQL 数据库实例或 Aurora 数据库集群关联。

创建代理

  1. 登录 AWS 管理控制台 并通过以下网址打开 Amazon RDS 控制台:https://console.amazonaws.cn/rds/

  2. 在导航窗格中,选择 Proxies (代理)

  3. 选择 Create proxy (创建代理)

  4. 为您的代理选择所有设置。对于公开预览版,某些选项是受限或必需的。请考虑以下准则:

    代理配置

    • 代理标识符。指定选择的名称,该名称在您的 AWS 账户 ID 和当前 AWS 区域内唯一。

    • 引擎兼容性。选择 MySQLPOSTGRESQL

    • 需要传输层安全性。如果希望代理对所有客户端连接强制执行 TLS/SSL,则选择此设置。如果您使用与代理的加密或未加密连接,则代理在与底层数据库建立连接时使用相同的加密设置。

    • 空闲客户端连接超时。选择在代理关闭客户端连接之前该连接可以处于空闲状态的时间段。默认值为 1800 秒(30 分钟)。如果应用程序未在上一请求完成后的指定时间内提交新请求,则客户端连接视为空闲。底层数据库连接保持打开状态并返回到连接池。因此,它可以重复用于新的客户端连接。

      如果您希望代理主动删除过时的连接,请考虑减少空闲客户端连接超时。如果您的工作负载会出现峰值,请考虑增加空闲客户端连接超时以节省建立连接的成本。

    目标组配置

    • 数据库。选择一个要通过此代理访问的 RDS 数据库实例或 Aurora 数据库集群。该列表仅包含具有兼容数据库引擎、引擎版本和其他设置的数据库实例和集群。如果列表为空,请创建与 RDS Proxy 兼容的新数据库实例或集群。然后尝试再次创建代理。

    • 连接池最大连接数。请指定 1 到 100 之间的值。此设置表示 RDS Proxy 可用于其连接的 max_connections 值的百分比。如果您只打算对此数据库实例或集群使用一个代理,可以将其设置为 100。有关 RDS Proxy 如何使用此设置的详细信息,请参阅 控制连接限制和超时

    • Session pinning filters (会话固定筛选条件)。这是一项高级设置,用于解决特定应用程序的性能问题。目前,唯一的选择是 EXCLUDE_VARIABLE_SETS。仅当您的应用程序由于某些类型的 SQL 语句而未重用连接,并且您可以验证使用这些 SQL 语句重用连接不会影响应用程序的正确性时,才选择一个筛选条件。有关更多信息,请参阅避免固定

    • Connection borrow timeout (连接借用超时)。在某些情况下,您可能希望代理在某些时候用尽所有可用的连接。在这种情况下,您可以指定在返回超时错误之前代理等待连接可用的时间。仅当代理已打开最大连接数并且所有连接均已在使用时,该设置才适用。

    Connectivity (连接)

    • Secrets Manager ARN。至少选择一个与要使用此代理访问的 RDS 数据库实例或 Aurora 数据库集群关联的 Secrets Manager 密钥。

    • IAM role (IAM 角色)。选择一个有权访问您之前所选 Secrets Manager 密钥的 IAM 角色。您还可以选择 AWS 管理控制台 来创建新 IAM 角色并使用该角色。

    • IAM Authentication (IAM 身份验证)。选择是要求还是禁止对代理连接进行 IAM 身份验证。

    • Subnets (子网)。此字段预填充与您的 VPC 关联的所有子网。您可以删除此代理不需要的任何子网。必须至少保留两个子网。

    Additional connectivity configuration (其他连接配置)

    • VPC security group (VPC 安全组)。选择现有的 VPC 安全组。您还可以选择 AWS 管理控制台 来创建新安全组并使用该安全组。

    Advanced configuration (高级配置)

    • Enable enhanced logging (启用增强型日志记录)。您可以启用该设置来解决代理兼容性或性能问题。启用该设置后,RDS Proxy 会在其日志中包含有关 SQL 语句的详细信息。这些信息可帮助您调试涉及 SQL 行为或代理连接的性能和可扩展性的问题。调试信息包括您通过代理提交的 SQL 语句的文本。因此,只有在需要调试,并且仅当您已采取安全措施来保护日志中显示的任何敏感信息时,才启用该设置。

  5. 选择 RDS Proxy is now available in Preview (RDS Proxy 现已在预览版中提供),以确认预览版的条款和条件。

  6. 选择 Create Proxy (创建代理)

要创建代理,请使用 AWS CLI 命令 create-db-proxy。请注意,--engine-family 值区分大小写。

对于 Linux、macOS 或 Unix:

aws rds create-db-proxy \ --db-proxy-name proxy_name \ --role-arn iam_role \ --engine-family { MYSQL | POSTGRESQL } \ --vpc-subnet-ids space_separated_list \ [--vpc-security-group-ids space_separated_list] \ [--auth ProxyAuthenticationConfig_JSON_string] \ [--require-tls | --no-require-tls] \ [--idle-client-timeout value] \ [--debug-logging | --no-debug-logging] \ [--tags comma_separated_list]

对于 Windows:

aws rds create-db-proxy ^ --db-proxy-name proxy_name ^ --role-arn iam_role ^ --engine-family { MYSQL | POSTGRESQL } ^ --vpc-subnet-ids space_separated_list ^ [--vpc-security-group-ids space_separated_list] ^ [--auth ProxyAuthenticationConfig_JSON_string] ^ [--require-tls | --no-require-tls] ^ [--idle-client-timeout value] ^ [--debug-logging | --no-debug-logging] ^ [--tags comma_separated_list]

要创建代理所需的信息和关联,您也可以使用 register-db-proxy-targets 命令。目前,所有代理都有一个名为 default 的目标组。Aurora 将自动为每个代理创建此目标组。

aws rds register-db-proxy-targets --db-proxy-name value [--target-group-name default] [--db-instance-identifiers space_separated_list] # rds db instances, or [--db-cluster-identifiers cluster_id] # rds db cluster (all instances), or [--db-cluster-endpoint endpoint_name] # rds db cluster endpoint (all instances)

要创建 RDS Proxy,请调用 Amazon RDS API 函数 CreateDBProxy。传递具有 AuthConfig 数据结构的参数。

目前,所有代理都有一个名为 default 的目标组。Aurora 将自动为每个代理创建此目标组。您可以通过调用函数 RegisterDBProxyTargets 将 RDS 数据库实例或 Aurora 数据库集群与目标组关联。

查看 RDS Proxy

创建一个或多个 RDS 代理后,您可以查看所有代理以检查其配置详细信息,并选择要修改、删除以及执行其他操作的代理。

特别是,您需要在使用代理的任何数据库应用程序的连接字符串中使用代理的终端节点。

查看您的 RDS Proxy

  1. 登录 AWS 管理控制台 并通过以下网址打开 Amazon RDS 控制台:https://console.amazonaws.cn/rds/

  2. 在 AWS 管理控制台 的右上角,选择在其中创建了 RDS Proxy 的 AWS 区域。

  3. 在导航窗格中,选择 Proxies (代理)

  4. 选择 RDS 代理的名称以显示其详细信息。

  5. 在详细信息页面上,Target groups (目标组) 部分显示了代理与特定 RDS 数据库实例或 Aurora 数据库集群的关联方式。您可以访问指向默认目标组页面的链接,以查看有关代理与数据库之间关联的更多详细信息。在该页面上,您可以看到创建代理时指定的设置,如最大连接百分比、连接借用超时、引擎兼容性和会话固定筛选条件。

要使用 CLI 查看您的 RDS Proxy,请使用 describe-db-proxies 命令。默认情况下,它会显示您的 AWS 账户拥有的所有代理。要查看单个代理的详细信息,请通过 --db-proxy-name 参数指定其名称。

aws rds describe-db-proxies [--db-proxy-name proxy_name]

要查看与该代理关联的其他信息,请使用以下命令:

aws rds describe-db-proxy-target-groups --db-proxy-name proxy_name aws rds describe-db-proxy-targets --db-proxy-name proxy_name

使用以下命令序列查看有关与代理关联的内容的更多详细信息:

要使用 RDS API 查看您的代理,请使用 DescribeDBProxies 操作。该操作将返回 DBProxy 数据类型的值。

您可以通过 DescribeDBProxyTargetGroups 操作,使用返回值中的代理标识符来查看代理连接设置的详细信息。该操作将返回 DBProxyTargetGroup 数据类型的值。

您可以通过使用 DescribeDBProxyTargets 操作来查看与代理关联的 RDS 实例或 Aurora 数据库集群。该操作将返回 DBProxyTarget 数据类型的值。

通过 RDS Proxy 连接到数据库

这是 Amazon RDS 代理的预览版文档。本文档随时可能更改。

通过代理连接到 RDS 数据库实例或 Aurora 数据库集群的方式通常与直接连接到数据库的方式相同。主要区别在于您指定代理终端节点而不是实例或集群终端节点。

对于 Aurora 数据库集群,所有代理连接都具有读写功能,并使用写入器实例。如果将读取器终端节点用于只读连接,则继续以相同的方式使用读取器终端节点。

对于 PostgreSQL,如果您使用 JDBC,则建议您将连接参数 assumeMinServerVersion 设置为至少 9.0 以避免固定。另请参阅 避免固定

使用本机身份验证连接到代理

按照以下常规过程,使用本机身份验证连接到代理:

  • 查找代理终端节点。在 AWS 管理控制台 中,您可以在相应代理的详细信息页面上找到终端节点。对于 AWS CLI,您可以使用 describe-db-proxies 命令。下面的示例演示了如何操作:

    # Add --output text to get output as a simple tab-separated list. $ aws rds describe-db-proxies --query '*[*].{DBProxyName:DBProxyName,Endpoint:Endpoint}' [ [ { "Endpoint": "the-proxy.proxy-demo.us-east-1.rds.amazonaws.com", "DBProxyName": "the-proxy" }, { "Endpoint": "the-proxy-other-secret.proxy-demo.us-east-1.rds.amazonaws.com", "DBProxyName": "the-proxy-other-secret" }, { "Endpoint": "the-proxy-rds-secret.proxy-demo.us-east-1.rds.amazonaws.com", "DBProxyName": "the-proxy-rds-secret" }, { "Endpoint": "the-proxy-t3.proxy-demo.us-east-1.rds.amazonaws.com", "DBProxyName": "the-proxy-t3" } ] ]
  • 在客户端应用程序的连接字符串中指定该终端节点作为主机参数。例如,指定代理终端节点作为 mysql -h 选项或 psql -h 选项的值。

  • 提供通常使用的相同的数据库用户名和密码。

使用 IAM 身份验证连接到代理

遵循与使用 IAM 身份验证连接到 RDS 数据库实例或 Aurora 集群相同的常规过程。指定代理终端节点,而不是实例、集群或读取器终端节点。有关详细信息,请参阅 使用 IAM 身份验证连接到数据库实例

使用 IAM 身份验证连接到代理时,必须使用传输层安全性 (TLS)/安全套接字层 (SSL)。

您可以通过修改 IAM 策略授予特定用户对代理的访问权限。例如:

"Resource": "arn:aws:rds-db:us-east-2:1234567890:dbuser:db-ABCDEFGHIJKL01234/db_user”

管理 RDS Proxy

这是 Amazon RDS 代理的预览版文档。本文档随时可能更改。

以下内容介绍了可帮助您的应用程序最有效地使用数据库连接并实现最大程度连接重用的 RDS Proxy 操作和配置方面。您越多地利用连接重用,就可以节省越多的 CPU 和内存开销。这进而减少了应用程序的延迟,使数据库能够将更多资源用于处理应用程序请求。

删除 RDS Proxy

如果您不再需要某个代理,可以将其删除。您可能因为正在使用某个代理的应用程序不再相关而删除该代理。或者,如果您停止使用数据库实例或与其关联的集群,则可以删除代理。

删除代理

  1. 登录 AWS 管理控制台 并通过以下网址打开 Amazon RDS 控制台:https://console.amazonaws.cn/rds/

  2. 在导航窗格中,选择 Proxies (代理)

  3. 从列表中选择要删除的代理。

  4. 选择 Delete Proxy (删除代理)

要删除数据库代理,请使用 AWS CLI 命令 delete-db-proxy。要删除相关的关联,还可以使用 deregister-db-proxy-targets 命令。

aws rds delete-db-proxy --name proxy_name
aws rds deregister-db-proxy-targets --db-proxy-name proxy_name [--target-group-name target_group_name] [--target-ids comma_separated_list] # or [--db-instance-identifiers instance_id] # or [--db-cluster-identifiers cluster_id]

要删除数据库代理,请调用 Amazon RDS API 函数 DeleteDBProxy。要删除相关项目和关联,您也可以调用函数 DeleteDBProxyTargetGroupDeregisterDBProxyTargets

修改 RDS Proxy

您可以在创建代理后更改与代理关联的某些设置。可通过修改代理本身和/或其关联的目标组来执行此操作。每个代理都有一个关联的目标组。

修改代理的设置

  1. 登录 AWS 管理控制台 并通过以下网址打开 Amazon RDS 控制台:https://console.amazonaws.cn/rds/

  2. 在导航窗格中,选择 Proxies (代理)

  3. 在代理列表中,选择要修改其设置的代理或转到其详细信息页面。

  4. 对于 Actions (操作),选择 Modify (修改)

  5. 输入或选择要修改的属性。您可执行以下操作:

    • 通过输入新标识符来重命名代理。

    • 打开或关闭传输层安全性 (TLS) 的要求。

    • 输入空闲连接超时的时间段。

    • 添加或删除 Secrets Manager 密钥。这些密钥对应于数据库用户名和密码。

    • 更改用于从 Secrets Manager 中检索密钥的 IAM 角色。

    • 要求或禁止对代理连接进行 IAM 身份验证。

    • 添加或删除供代理使用的 VPC 子网。

    • 添加或删除供代理使用的 VPC 安全组。

    • 启用或禁用增强型日志记录。

  6. 选择修改

如果找不到要更改的设置,请继续执行以下过程以更新代理的目标组。每个代理都有一个关联的目标组,该目标组与代理一起自动创建。

修改代理目标组的设置

与代理关联的目标组控制与物理数据库连接相关的设置。您只能从代理详细信息页面修改目标组,而不能从 Proxies (代理) 页面上的列表中进行修改。

  1. Proxies (代理) 页面转到代理的详细信息页面。

  2. 对于 Target groups (目标组),选择 default 链接。目前,所有代理都有一个名为 default 的目标组。

  3. 默认目标组的详细信息页面上,选择 Modify (修改)

  4. 某些属性(如目标组标识符和数据库引擎)是固定的。您无法更改这些属性。

    为您可以修改的属性选择新设置:

    • 可以选择不同的 RDS 数据库实例或 Aurora 集群。

    • 可以调整代理可使用的最大可用连接的百分比。

    • 可以选择会话固定筛选条件。该设置可帮助减少由于事务级别的连接重用不足而导致的性能问题。要使用该设置,您需要了解应用程序行为以及 RDS Proxy 将会话固定到数据库连接的情况。

    • 您可以调整连接借用超时间隔。该设置确定代理在返回超时错误(此时代理正使用的连接数已达最大)之前等待连接变为可用的时间。

  5. 选择 Modify target group (修改目标组)

要使用 AWS CLI 修改代理,请使用 modify-db-proxymodify-db-proxy-target-groupderegister-db-proxy-targetsregister-db-proxy-targets 命令。

使用 modify-db-proxy 命令,您可以更改以下属性:

  • 代理使用的一组 Secrets Manager 密钥。

  • 是否需要 TLS。

  • 空闲客户端超时。

  • 是否记录 SQL 语句中的其他信息以进行调试。

  • 用于检索 Secrets Manager 密钥的 IAM 角色。

  • 代理使用的安全组。

以下示例演示了如何重命名现有代理。

aws rds modify-db-proxy --db-proxy-name the-proxy --new-db-proxy-name the_new_name

使用 modify-db-proxy-target-group 命令,您可以修改与连接相关的设置或重命名目标组。目前,所有代理都有一个名为 default 的目标组。使用此目标组时,请指定代理的名称,并指定 default 作为目标组的名称。

以下示例演示了如何首先检查代理的 MaxConnectionsPercent 设置,然后使用目标组对其进行更改。

aws rds describe-db-proxy-target-groups --db-proxy-name the-proxy { "TargetGroups": [ { "Status": "available", "UpdatedDate": "2019-11-30T16:49:30.342Z", "ConnectionPoolConfig": { "MaxIdleConnectionsPercent": 50, "ConnectionBorrowTimeout": 120, "MaxConnectionsPercent": 100, "SessionPinningFilters": [] }, "TargetGroupName": "default", "CreatedDate": "2019-11-30T16:49:27.940Z", "DBProxyName": "the-proxy", "IsDefault": true } ] } aws rds modify-db-proxy-target-group --db-proxy-name the-proxy --target-group-name default --connection-pool-config ' { "MaxIdleConnectionsPercent": 75 }' { "DBProxyTargetGroup": { "Status": "available", "UpdatedDate": "2019-12-02T04:09:50.420Z", "ConnectionPoolConfig": { "MaxIdleConnectionsPercent": 75, "ConnectionBorrowTimeout": 120, "MaxConnectionsPercent": 100, "SessionPinningFilters": [] }, "TargetGroupName": "default", "CreatedDate": "2019-11-30T16:49:27.940Z", "DBProxyName": "the-proxy", "IsDefault": true } }

使用 deregister-db-proxy-targetsregister-db-proxy-targets 命令,您可以通过相应的目标组来更改代理关联的 RDS 数据库实例或 Aurora 数据库集群。目前,每个代理都可以连接到一个 RDS 数据库实例或 Aurora 数据库集群。目标组可跟踪多可用区配置中的所有 RDS 数据库实例或 Aurora 集群中所有数据库实例的连接详细信息。

以下示例首先介绍了与名为 cluster-56-2020-02-25-1399 的 Aurora MySQL 集群关联的代理。该示例演示了如何更改代理,以便连接到名为 provisioned-cluster 的不同集群。使用 RDS 数据库实例时,请指定 --db-instance-identifier 选项。使用 Aurora 数据库集群时,则指定 --db-cluster-identifier 选项。以下示例修改 Aurora MySQL 代理。Aurora PostgreSQL 代理使用端口 5432。

aws rds describe-db-proxy-targets --db-proxy-name the-proxy { "Targets": [ { "Endpoint": "instance-9814.demo.us-east-1.rds.amazonaws.com", "Type": "RDS_INSTANCE", "Port": 3306, "RdsResourceId": "instance-9814" }, { "Endpoint": "instance-8898.demo.us-east-1.rds.amazonaws.com", "Type": "RDS_INSTANCE", "Port": 3306, "RdsResourceId": "instance-8898" }, { "Endpoint": "instance-1018.demo.us-east-1.rds.amazonaws.com", "Type": "RDS_INSTANCE", "Port": 3306, "RdsResourceId": "instance-1018" }, { "Type": "TRACKED_CLUSTER", "Port": 0, "RdsResourceId": "cluster-56-2020-02-25-1399" }, { "Endpoint": "instance-4330.demo.us-east-1.rds.amazonaws.com", "Type": "RDS_INSTANCE", "Port": 3306, "RdsResourceId": "instance-4330" } ] } aws rds deregister-db-proxy-targets --db-proxy-name the-proxy --db-cluster-identifier cluster-56-2020-02-25-1399 aws rds describe-db-proxy-targets --db-proxy-name the-proxy { "Targets": [] } aws rds register-db-proxy-targets --db-proxy-name the-proxy --db-cluster-identifier provisioned-cluster { "DBProxyTargets": [ { "Type": "TRACKED_CLUSTER", "Port": 0, "RdsResourceId": "provisioned-cluster" }, { "Endpoint": "gkldje.demo.us-east-1.rds.amazonaws.com", "Type": "RDS_INSTANCE", "Port": 3306, "RdsResourceId": "gkldje" }, { "Endpoint": "provisioned-1.demo.us-east-1.rds.amazonaws.com", "Type": "RDS_INSTANCE", "Port": 3306, "RdsResourceId": "provisioned-1" } ] }

要使用 RDS API 修改代理,请使用 ModifyDBProxyModifyDBProxyTargetGroupDeregisterDBProxyTargetsRegisterDBProxyTargets 操作。

使用 ModifyDBProxy,您可以更改以下属性:

  • 代理使用的一组 Secrets Manager 密钥。

  • 是否需要 TLS。

  • 空闲客户端超时。

  • 是否记录 SQL 语句中的其他信息以进行调试。

  • 用于检索 Secrets Manager 密钥的 IAM 角色。

  • 代理使用的安全组。

使用 ModifyDBProxyTargetGroup,您可以修改与连接相关的设置或重命名目标组。目前,所有代理都有一个名为 default 的目标组。使用此目标组时,请指定代理的名称,并指定 default 作为目标组的名称。

使用 DeregisterDBProxyTargetsRegisterDBProxyTargets,您可以通过相应的目标组来更改代理关联的 RDS 数据库实例或 Aurora 数据库集群。目前,每个代理都可以连接到一个 RDS 数据库实例或 Aurora 数据库集群。目标组可跟踪多可用区配置中的所有 RDS 数据库实例或 Aurora 集群中所有数据库实例的连接详细信息。

添加新数据库用户

在某些情况下,您可能会将新数据库用户添加到与代理关联的 RDS 数据库实例或 Aurora 集群。如果是这样,请添加 Secrets Manager 密钥或调整其用途,以存储该用户的凭证。为此,请选择以下选项之一:

更改数据库用户的密码

在某些情况下,您可能会更改与代理关联的 RDS 数据库实例或 Aurora 集群中的数据库用户的密码。如果是这样,请使用新密码更新相应的 Secrets Manager 密钥。

控制连接限制和超时

RDS Proxy 对 RDS 数据库实例或 Aurora 数据库集群使用 max_connections 设置。该设置表示代理在任何一个时刻可以打开的连接数量的总体上限。在 Aurora 集群和 RDS 多可用区配置中,代理使用的 max_connections 值是 Aurora 主实例或 RDS 写入器实例的值。

最大连接数的代理设置表示 max_connections 值的百分比。如果有多个应用程序都使用同一数据库,您可以通过对每个应用程序使用一个代理来有效地划分其连接配额(按 max_connections 的特定百分比)。如果执行此操作,请确保与同一数据库关联的所有代理的百分比加起来不超过 100%。

RDS Proxy 定期断开空闲连接并将其返回到连接池。您可以调整此超时间隔。这样做可帮助您的应用程序处理过时的资源(特别是如果应用程序错误地在保留重要数据库资源的同时使连接保持打开状态)。

监控和管理连接池

连接池 中的概念所述,连接池是一个关键 RDS Proxy 功能。接下来,您可以了解如何最有效地利用连接池和事务级别连接重用(多路复用)。

由于连接池由 RDS Proxy 托管,您可以对其进行监控并调整连接限制和超时间隔,而无需更改应用程序代码。

对于每个代理,您可以为连接池使用的连接数指定上限。请将限制指定为百分比。该百分比适用于数据库中配置的最大连接数。确切数字因数据库实例大小和配置设置而异。

例如,假设您将 RDS Proxy 配置为使用数据库最大连接数的 75%。对于 MySQL,最大值由 max_connections 配置参数定义。在这种情况下,其他 25% 的最大连接数仍可用于分配给其他代理或作为不经过代理的连接。在某些情况下,代理可能会在特定时间保持低于 75% 的最大打开连接数。这些情况可能包括数据库没有多个并发连接的情况,或者某些连接长时间处于空闲状态的情况。

当您更新适用于 RDS 数据库实例或 Aurora 集群的 max_connections 配置设置时,可用于连接池的总连接数会发生变化。

代理不会提前保留所有这些连接。因此,您可以指定一个相对较大的百分比,只有当代理变得足够忙而需要它们时才会打开这些连接。

您可以选择等待连接可供应用程序使用的时间。创建代理时,该设置由 Connection borrow timeout (连接借用超时) 选项表示。该设置指定在返回超时错误之前等待连接池中的连接可用的时间。这适用于连接数达到最大而导致连接池中没有可用连接的情况。如果由于正在进行故障转移操作而没有可用的写入器实例,那么这也适用。通过该设置,您可以限制最适合应用程序的等待期,而无需更改应用程序代码中的查询超时。

避免固定

当数据库请求不依赖于先前请求的状态信息时,多路复用效率更高。在这种情况下,RDS Proxy 可以在每个事务结束时重用连接。此类状态信息的示例包括可通过 SETSELECT 语句更改的大多数变量和配置参数。默认情况下,客户端连接上的 SQL 事务可以在底层数据库连接之间多路复用。

与代理的连接可以进入一种称为固定的状态。固定连接后,每个后续事务都使用同一底层数据库连接,直到会话结束。RDS Proxy 在检测到不适合其他会话的会话状态更改时,会自动将客户端连接固定到特定数据库连接。固定降低了连接重用的有效性。如果您的所有连接或几乎所有连接都遇到固定,请考虑修改应用程序代码或工作负载,以减少导致固定的条件。

例如,如果您的应用程序更改了会话变量或配置参数,则后续语句可以依赖将要生效的新变量或参数。因此,当 RDS Proxy 处理更改会话变量或配置设置的请求时,它会将该会话固定到数据库连接。这样,会话状态对于同一会话中的所有后续事务仍然有效。

这项规则并不对您可以设置的所有参数均适用。RDS Proxy 会跟踪对字符集、排序规则、时区、自动提交、当前数据库、SQL 模式和 session_track_schema 设置的更改。因此在您修改这些内容时,RDS Proxy 不会固定会话。在这种情况下,RDS Proxy 仅将连接重用于具有相同设置值的其他会话。

RDS Proxy 的性能优化包括尝试通过最小化固定来最大化事务级别连接重用(多路复用)。您可以通过使用以下方法来执行此操作:

  • 避免可能导致固定的不必要的数据库请求。

  • 在所有连接中一致地设置变量和配置设置。这样,后续会话更有可能重用具有这些特定设置的连接。

    但是,对于 PostgreSQL 设置,变量将导致会话固定。

  • 将会话固定筛选条件应用于代理。您可以免除某些类型的操作,使其不固定会话(如果您知道这样做不会影响应用程序的正确操作)。

  • 监控 CloudWatch 指标 DatabaseConnectionsCurrentlySessionPinned 以查看固定发生的频率。有关该指标和其他 CloudWatch 指标的信息,请参阅 使用 Amazon CloudWatch 监控 RDS Proxy

  • 如果您使用 SET 语句为每个客户端连接执行相同的初始化,则可以在仍保留事务级别多路复用的同时执行此操作。在这种情况下,您将设置初始会话状态的语句移动到由代理使用的初始化查询中。该属性是一个字符串,包含一个或多个 SQL 语句(用分号分隔)。例如,您可以为设置特定配置参数的代理定义初始化查询。然后,每当为该代理设置新连接时,RDS Proxy 都会应用这些设置。您可以从应用程序代码中删除相应的 SET 语句,这样,它们就不会干扰事务级别多路复用。

    您可以通过 AWS CLI 和 RDS API 处理初始化查询。目前,您无法通过 AWS 管理控制台 设置该属性。对于 PostgreSQL,当前不实施初始化查询。

对于以下情况(其中多路复用可能会导致意外行为),代理将会话固定到当前连接:

  • 文本大小大于 4 KB 的任何语句都会导致代理固定会话。

  • 预编译语句会导致代理固定会话。无论预编译语句使用 SQL 文本还是二进制协议,这项规则都适用。

  • 显式 MySQL 语句 LOCK TABLELOCK TABLESFLUSH TABLES WITH READ LOCK 会导致代理固定会话。

  • 设置用户变量或系统变量(有些例外)会导致代理固定会话。如果这种情况过多地减少了连接重用,您可以选择让 SET 操作不导致固定。

  • 创建临时表会导致代理固定会话。这样,无论事务边界如何,临时表的内容都会在整个会话期间保留。

  • 调用 MySQL 函数 ROW_COUNT()FOUND_ROWS()LAST_INSERT_ID() 有时会导致固定,有时不会。

    与 MySQL 5.6 和 MySQL 5.7 兼容的 Aurora MySQL 版本之间的行为可能会有所不同。

调用 MySQL 存储过程和存储函数不会导致固定。RDS Proxy 不会检测此类调用导致的任何会话状态更改。因此,请确保您的应用程序不会更改存储例程中的会话状态,并依赖该会话状态跨事务持续存在。例如,如果存储过程创建了一个旨在跨事务持续存在的临时表,则该应用程序当前不与 RDS Proxy 兼容。

对于 PostgreSQL,以下交互会导致固定:

  • 使用 SET 命令

  • 使用扩展查询协议,例如使用 JDBC 默认设置

  • 创建临时序列、表或视图

  • 声明游标

  • 丢弃会话状态

  • 监听通知频道

  • 加载库模块,如 auto_explain

  • 使用函数操作序列,例如 nextval()setval()

  • 使用函数与锁定交互,例如 pg_advisory_lock()pg_try_advisory_lock()

  • 使用预编译语句,设置参数或将参数重置为其默认值

如果您拥有关于应用程序行为的专业知识,则可以选择跳过某些应用程序语句的固定行为。您可以在创建代理时选择 Session pinning filters (会话固定筛选条件) 选项来执行此操作。目前,您可以选择退出以下类型应用程序语句的会话固定:

  • 设置会话变量和配置设置。

要查看有关代理的固定发生频率的指标,请参阅 使用 Amazon CloudWatch 监控 RDS Proxy

使用 Amazon CloudWatch 监控 RDS Proxy

这是 Amazon RDS 代理的预览版文档。本文档随时可能更改。

您可以使用 Amazon CloudWatch 监控 RDS Proxy。CloudWatch 可从代理收集原始数据,并将数据处理为便于读取的近乎实时的指标。要在 CloudWatch 控制台中查找这些指标,请依次选择 Metrics (指标)RDSPer-Proxy Metrics (每个代理指标)

注意

RDS 为与代理关联的每个底层 EC2 实例发布这些指标。一个代理可能由多个 EC2 实例提供服务。使用 CloudWatch 统计数据可汇总所有关联实例的代理值。

其中一些指标可能在代理第一次成功连接之后才可见。

所有 RDS Proxy 指标都在组 proxy 中,其维度为 ProxyName

指标 有效期 描述

ClientConnectionsReceived

1 分钟及更久

收到的客户端连接请求数。该指标最有用的统计数据是 Sum。

ClientConnectionsSetupSucceeded

1 分钟及更久

使用任何具有或不具有 TLS 的身份验证机制成功建立的客户端连接数。该指标最有用的统计数据是 Sum。

ClientConnectionsSetupFailedAuth

1 分钟及更久

由于身份验证错误或 TLS 配置错误而失败的客户端连接尝试次数。该指标最有用的统计数据是 Sum。

ClientConnectionsClosed

1 分钟及更久

已关闭的客户端连接数。该指标最有用的统计数据是 Sum。

ClientConnections

1 minute

当前客户端连接数。每分钟报告一次。该指标最有用的统计数据是 Sum。

QueryRequests

1 分钟及更久

收到的查询数。注意:多语句查询计为一个查询。该指标最有用的统计数据是 Sum。

DatabaseConnectionRequests

1 分钟及更久

创建数据库连接的请求数。该指标最有用的统计数据是 Sum。

DatabaseConnectionsSetupSucceeded

1 分钟及更久

使用或不使用 TLS 成功建立的数据库连接数。该指标最有用的统计数据是 Sum。

DatabaseConnectionsSetupFailed

1 分钟及更久

失败的数据库连接请求数。该指标最有用的统计数据是 Sum。

MaxDatabaseConnectionsAllowed

1 minute

允许的最大数据库连接数。每分钟报告一次。该指标最有用的统计数据是 Sum。

DatabaseConnections

1 minute

当前数据库连接数。每分钟报告一次。该指标最有用的统计数据是 Sum。

DatabaseConnectionsCurrentlyBorrowed

1 minute

当前处于借用状态的数据库连接数。每分钟报告一次。该指标最有用的统计数据是 Sum。

DatabaseConnectionsCurrentlySessionPinned

1 minute

当前由于客户端请求中的会话状态更改操作而固定的当前数据库连接数。每分钟报告一次。该指标最有用的统计数据是 Sum。

DatabaseConnectionsCurrentlyInTransaction

1 minute

事务中的当前数据库连接数。每分钟报告一次。该指标最有用的统计数据是 Sum。

TargetGroupWriterAvailableDuration

1 minute

一分钟持续时间内目标组具有写入器的秒数。每分钟报告一次。该指标最有用的统计数据是 Average。

RDS Proxy 的命令行示例

这是 Amazon RDS 代理的预览版文档。本文档随时可能更改。

要了解连接命令和 SQL 语句的组合如何与 RDS Proxy 交互,请查看以下示例。

跨故障转移保留与 MySQL 数据库的连接

本 MySQL 示例演示了打开的连接在故障转移(例如当您重新启动数据库或数据库由于某个问题而变得不可用时)期间如何继续工作。本示例使用一个名为 the-proxy 的代理,以及一个包含数据库实例 instance-8898instance-9814 的 Aurora 数据库集群。从 Linux 命令行运行 failover-db-cluster 命令时,代理连接到的写入器实例将更改为不同的数据库实例。您可以看到,与代理关联的数据库实例在连接保持打开状态时发生更改。

$ mysql -h the-proxy.proxy-demo.us-east-1.rds.amazonaws.com -u admin_user -p Enter password: ... mysql> select @@aurora_server_id; +--------------------+ | @@aurora_server_id | +--------------------+ | instance-9814 | +--------------------+ 1 row in set (0.01 sec) mysql> [1]+ Stopped mysql -h the-proxy.proxy-demo.us-east-1.rds.amazonaws.com -u admin_user -p $ # Initially, instance-9814 is the writer. $ aws rds failover-db-cluster --db-cluster-id cluster-56-2019-11-14-1399 JSON output $ # After a short time, the console shows that the failover operation is complete. $ # Now instance-8898 is the writer. $ fg mysql -h the-proxy.proxy-demo.us.us-east-1.rds.amazonaws.com -u admin_user -p mysql> select @@aurora_server_id; +--------------------+ | @@aurora_server_id | +--------------------+ | instance-8898 | +--------------------+ 1 row in set (0.01 sec) mysql> [1]+ Stopped mysql -h the-proxy.proxy-demo.us-east-1.rds.amazonaws.com -u admin_user -p $ aws rds failover-db-cluster --db-cluster-id cluster-56-2019-11-14-1399 JSON output $ # After a short time, the console shows that the failover operation is complete. $ # Now instance-9814 is the writer again. $ fg mysql -h the-proxy.proxy-demo.us-east-1.rds.amazonaws.com -u admin_user -p mysql> select @@aurora_server_id; +--------------------+ | @@aurora_server_id | +--------------------+ | instance-9814 | +--------------------+ 1 row in set (0.01 sec) +---------------+---------------+ | Variable_name | Value | +---------------+---------------+ | hostname | ip-10-1-3-178 | +---------------+---------------+ 1 row in set (0.02 sec)

调整 Aurora 数据库集群的 max_connections 设置

本示例演示如何调整 Aurora MySQL 数据库集群的 max_connections 设置。为此,请根据与 MySQL 5.6 或 5.7 兼容的集群的默认参数设置,创建自己的数据库集群参数组。您可以为 max_connections 设置指定一个值,从而覆盖设置默认值的公式。将数据库集群参数组与数据库集群关联。

export REGION=us-east-1 export CLUSTER_PARAM_GROUP=rds-proxy-mysql-56-max-connections-demo export CLUSTER_NAME=rds-proxy-mysql-56 aws rds create-db-parameter-group --region $REGION \ --db-parameter-group-family aurora5.6 \ --db-parameter-group-name $CLUSTER_PARAM_GROUP \ --description "Aurora MySQL 5.6 cluster parameter group for RDS Proxy demo." aws rds modify-db-cluster --region $REGION \ --db-cluster-identifier $CLUSTER_NAME \ --db-cluster-parameter-group-name $CLUSTER_PARAM_GROUP echo "New cluster param group is assigned to cluster:" aws rds describe-db-clusters --region $REGION \ --db-cluster-identifier $CLUSTER_NAME \ --query '*[*].{DBClusterParameterGroup:DBClusterParameterGroup}' echo "Current value for max_connections:" aws rds describe-db-cluster-parameters --region $REGION \ --db-cluster-parameter-group-name $CLUSTER_PARAM_GROUP \ --query '*[*].{ParameterName:ParameterName,ParameterValue:ParameterValue}' \ --output text | grep "^max_connections" echo -n "Enter number for max_connections setting: " read answer aws rds modify-db-cluster-parameter-group --region $REGION --db-cluster-parameter-group-name $CLUSTER_PARAM_GROUP \ --parameters "ParameterName=max_connections,ParameterValue=$$answer,ApplyMethod=immediate" echo "Updated value for max_connections:" aws rds describe-db-cluster-parameters --region $REGION \ --db-cluster-parameter-group-name $CLUSTER_PARAM_GROUP \ --query '*[*].{ParameterName:ParameterName,ParameterValue:ParameterValue}' \ --output text | grep "^max_connections"

RDS Proxy 故障排除

这是 Amazon RDS 代理的预览版文档。本文档随时可能更改。

常见问题和解决方案

您可以参考以下症状列表,以查看使用 RDS Proxy 时也许会遇到的问题的可能原因和解决方案。在公开预览版期间,错误处理代码不完整,因此您可能会遇到来自底层服务的神秘错误消息。

创建新代理或连接到代理时,您可能会遇到以下问题。

错误或症状 原因或解决方法

403: The security token included in the request is invalid

选择现有 IAM 角色,而不是选择创建新角色。

连接到 MySQL 代理时,您可能会遇到以下问题。

错误或症状 原因或解决方法
ERROR 1040 (HY000): Connections rate limit exceeded (*limit value*) 从客户端到代理的连接请求速率超过了限制。
ERROR 1040 (HY000): IAM authentication rate limit exceeded 从客户端到代理的具有 IAM 身份验证的并发请求数超过了限制。
ERROR 1040 (HY000): Number simultaneous connections exceeded (*limit value*) 从客户端到代理的并发连接请求数超出了限制。

ERROR 1045 (28000): Access denied for user 'DB_USER'@'%' (using password: YES)

一些可能的原因包括:

  • 代理使用的 Secrets Manager 密钥有一个轮换周期。不要为 RDS 代理使用的密钥启用轮换。

ERROR 1105 (HY000): Unknown error 出现未知错误。
ERROR 1231 (42000): Variable ''character_set_client'' can't be set to the value of *value*

character_set_client 参数设置的值无效。例如,值 ucs2 无效,因为它会导致 MySQL 服务器崩溃。

ERROR 2026 (HY000): SSL connection error: Internal Server *Error*

与代理的 TLS 握手失败。一些可能的原因包括:

  • SSL 是必需的,但服务器不支持它。

  • 发生内部服务器错误。

  • 发生握手错误。

ERROR 9501 (HY000): Timed-out waiting to acquire database connection

等待获取数据库连接时代理超时。一些可能的原因包括:

  • 代理无法建立数据库连接,因为已达到最大连接数

  • 代理无法建立数据库连接,因为数据库不可用。

连接到 PostgreSQL 代理时,您可能会遇到以下问题。

错误 原因 解决方案

IAM authentication is allowed only with SSL connections.

用户在 PostgreSQL 客户端中,尝试使用具有设置 sslmode=disable 的 IAM 身份验证连接到数据库。

用户需要在 PostgreSQL 客户端中使用最小设置 sslmode=require 连接到数据库。有关更多信息,请参阅 PostgreSQL SSL 支持文档。

This RDS Proxy requires TLS connections.

用户启用了设置“Require Transport Layer Security (需要传输层安全性)”,但尝试在 PostgreSQL 客户端中使用“sslmode=disable”进行连接。

用户需要执行以下任一操作:

  • 禁用代理的 Require Transport Layer Security (需要传输层安全性) 设置。

  • 在 PostgreSQL 客户端中,使用最小设置 sslmode=allow 连接到数据库。

IAM authentication failed for user username. Check the IAM token for this user and try again.

这可能是由于以下原因:

  • 客户端提供了错误的 IAM 用户名。

  • 客户端向用户提供了错误的 IAM 授权令牌

  • 客户端在使用没有所需权限的 IAM 策略。

  • 客户端向用户提供了过期的 IAM 授权令牌。

要修复此错误,请执行以下操作:

  1. 确认提供的 IAM 用户存在。

  2. 确认 IAM 授权令牌属于提供的 IAM 用户。

  3. 确认 IAM 策略具有足够的 RDS 权限。

  4. 检查所用 IAM 授权令牌的有效性。

CloudWatch 日志

您可以在 AWS 管理控制台 中的 CloudWatch 下找到 RDS Proxy 活动的日志。每个代理在 Log groups (日志组) 页面中都有一个条目。

重要

这些日志供相关人员进行故障排除,而不是用于编程访问。日志的格式和内容可能会发生变化(特别是在预览版期间)。

验证与代理的连接

您可以使用以下命令验证连接机制的所有组件是否均可与其他组件进行通信。

使用 describe-db-proxies 命令检查代理本身。另外使用 describe-db-proxy-target-groupsdescribe-db-proxy-targets 命令检查关联的目标组和目标组中指定的目标。检查目标的详细信息是否与您打算与代理关联的 RDS 数据库实例或 Aurora 数据库集群匹配。

aws rds describe-db-proxies --db-proxy-name $DB_PROXY_NAME aws rds describe-db-proxy-target-groups --db-proxy-name $DB_PROXY_NAME aws rds describe-db-proxy-targets --db-proxy-name $DB_PROXY_NAME

如果以下 Netcat 命令 (nc) 成功,您可以从登录的 EC2 实例或其他系统访问代理终端节点。如果您与代理和关联数据库不在同一 VPC 中,则该命令将报告失败。您可能未在同一 VPC 中就可以直接登录到数据库。但是,除非在同一 VPC 中,否则无法登录到代理。

nc -zx MySQL_proxy_endpoint 3306 nc -zx PostgreSQL_proxy_endpoint 5432

您可以使用以下命令来确保 EC2 实例具有所需属性。特别是,EC2 实例的 VPC 必须与代理连接到的 RDS 数据库实例或 Aurora 数据库集群的 VPC 相同。

aws ec2 describe-instances --instance-ids your_ec2_instance_id

检查用于代理的 Secrets Manager 密钥。

aws secretsmanager list-secrets aws secretsmanager get-secret-value --secret-id your_secret_id

确保 get-secret-value 显示的 SecretString 字段被编码为包含 usernamepassword 字段的 JSON 字符串。以下示例显示了 SecretString 字段的格式。

{ "ARN": "some_arn", "Name": "some_name", "VersionId": "some_version_id", "SecretString": '{"username":"some_username","password":"some_password"}', "VersionStages": [ "some_stage" ], "CreatedDate": some_timestamp }

检查与代理关联的 RDS 数据库实例或 Aurora 数据库集群。对于 Aurora 数据库集群,还要检查集群中的每个数据库实例。确保它们的属性与代理预期的属性相匹配,例如端口对于 MySQL 为 3306,对于 PostgreSQL 为 5432。

aws rds describe-db-clusters --db-cluster-id $DB_CLUSTER_ID aws rds describe-db-instances --db-instance-id $DB_INSTANCE_ID1 aws rds describe-db-instances --db-instance-id $DB_INSTANCE_ID2