View a markdown version of this page

应用程序和工作负载注意事项 - Amazon Aurora

应用程序和工作负载注意事项

多租户和多用户环境

在涉及可扩展性和改进连接管理时,使用 RDS 代理的好处取决于其执行连接池的能力,在更大程度上取决于连接多路复用的能力。连接池可以减少与打开和关闭连接相关的开销。借助连接多路复用,代理可以在事务完成后重复使用后端数据库连接。有关更多信息,请参阅 RDS 代理概念和术语

当连接无法多路复用时,代理会回退到一种称为连接固定的行为。固定是指客户端在整个会话期间被迫使用同一底层代理连接的情况。代理连接是为该客户端保留的,因此无法被其他客户端重复使用。换句话说,固定会在客户端-代理连接和代理-数据库连接之间创建一个独占的 1:1 关联。在所有主要出于可扩展性和效率原因使用 RDS 代理的场景中,避免固定是非常重要的。有关最新的固定行为,请参阅 避免固定 RDS 代理

一般来说,当连接具有相同状态时,可以进行多路复用。当连接包含会话特定的自定义状态信息时,无法进行多路复用。定义会话状态的一个方面是与连接相关联的数据库用户名。当您以“user_A”身份连接到代理时,代理也需要以“user_A”身份打开后端数据库连接。代理可能会将此后端连接放入连接池,并重复用于其他以“user_A”身份登录的客户端,但不能用于使用不同用户名的客户端。

在拥有大量唯一数据库账户的多用户环境中,这种行为可能会显著降低连接池和多路复用的效率。在使用数据库级或架构级多租户的架构中,尤其如此。如果数据库包含一千个架构(每个租户一个),并且每个租户使用不同的用户名连接数据库,连接池将被分割成特定于用户的微池,导致降低整体效率。

此外,数据库引擎的特定方面可能会进一步影响连接池效率和代理多路复用连接的能力:

  1. 在 Amazon RDS 和 Aurora PostgreSQL 中,多租户通常通过每个租户使用一个数据库的方式来实施。不过,在 PostgreSQL 中,连接是特定于数据库的:对一个数据库打开的连接不能访问其他数据库的数据。因此,数据库级别的多租户会降低代理级别的连接池和多路复用的效率。如果工作负载使用架构级别的多租户并且客户端会话使用自定义 search_path,这一考虑因素也同样适用。但是,如果所有会话都使用默认搜索路径并使用完全限定名称(schema_name.table_name)引用表,则这些会话可以进行多路复用。

  2. 在 Amazon RDS 和 Aurora MySQL 中,术语“数据库”和“架构”是同义词。多租户通常通过为每个租户使用一个架构的方式来实施,在 MySQL 中,这与为每个租户使用一个数据库是一样的。连接是针对整个 MySQL 服务器打开的,并不绑定到某个架构。如果应用程序使用架构级别的多租户,即使这些连接需要访问不同架构中的数据,对于使用同一数据库用户名的多个客户端,连接多路复用仍然是可能的。如果在应用程序级别进行租户隔离,而不是为每个租户使用不同的数据库账户,多路复用将是最有效的。

在多架构环境中,多路复用的效率取决于您如何引用表名:

  • 如果客户端使用会话变量(在 PostgreSQL 中为 SET search_path ...,在 MySQL 中为 USE schema;)选择当前架构,然后在查询中使用未限定表名(例如 SELECT ... FROM table_name),连接多路复用仅在使用同一架构或同一搜索路径的客户端之间起作用。

  • 如果客户端不修改会话状态来定义当前架构,而是在 SQL 语句中使用完全限定表名(例如 SELECT ... FROM schema_name.table_name),多路复用没有类似的限制。

为多个应用程序或软件堆栈提供服务的数据库

如上一部分中所述,某些连接状态特性不会导致固定,但仍会降低代理在不同客户端之间重复使用连接的能力。与 MySQL 目标一起使用时,RDS 代理会跟踪许多用于配置会话状态(例如字符集、时区和排序规则设置)的语句和会话变量。当客户端使用所跟踪的语句或变量来配置会话设置时,代理连接只能由其他具有相同设置值的客户端重复使用。

因此,某些应用程序和驱动程序的行为可能会降低您在代理内重复使用连接的能力。例如,您可以允许不同应用程序使用同一用户名连接到数据库(假设代理能够在这些应用程序之间重复使用和多路复用连接)。不过,如果一个应用程序使用时区 A(SET time_zone = ?)引导连接,而另一个应用程序使用时区 B,则连接在一个应用程序内部是可重复使用的,但在应用程序之间不可重复使用。这会导致连接池碎片化,从而对连接池和多路复用的效率产生负面影响。

有关更多信息,请参阅 RDS 代理针对 Aurora MySQL 数据库跟踪的内容。对于除 MySQL 之外的数据库目标,当前不支持会话状态跟踪。

有关管理会话状态以避免连接固定的配置指南和最佳实践,请参阅配置准则

将应用程序级连接池和高级驱动程序与 RDS 代理结合使用

在应用程序自身不使用连接池的情况下,RDS 代理有助于提高可扩展性和连接效率。与此同时,许多驱动程序和框架确实包括连接池功能。您可能同时在使用高级包装器或驱动程序,用于在驱动程序级别实施代理的一些功能。

使用应用程序级连接池和其他连接处理改进功能,本质上与使用 RDS 代理并不冲突,也不会抵消其好处。例如,您可能在应用程序容器中使用连接池,但由于容器数量太多,如果不使用代理,您仍然会超过数据库连接限制。将 RDS 代理与应用程序级连接池及其他连接相关功能一起使用时,请查看并了解在应用程序级别存在高级连接处理功能的原因。决定哪些功能值得保留(或无害),哪些功能可能与代理行为重叠或造成干扰。例如:

  1. 即使看起来与 RDS 代理功能重叠,内置于驱动程序和框架中的连接池功能仍然可能有用。如果应用程序级连接池在代理提供的好处基础上提高了本地连接效率,就可以保留该连接池。

  2. 与失效转移处理相关的功能可能会干扰 RDS 代理的逻辑,或者增加整体堆栈复杂性,而不会带来任何好处。例如,如果您的应用程序正在主动跟踪 Aurora 集群的拓扑结构以避免与 DNS 相关的失效转移延迟,就无需再使用 RDS 代理执行此操作。保留这种拓扑跟踪逻辑可能会导致不希望的行为,例如应用程序线程绕过代理,直接连接到各个数据库实例。在这种情况下,您可以禁用应用程序级别的跟踪逻辑,让 RDS 代理为您对集群拓扑进行抽象处理。

  3. 连接池库可能会使用在理论上看起来有益,但会干扰代理行为的状态管理功能。其中一个例子是,PostgreSQL 库会调用 DISCARD ALL 查询,在借用之间重置连接状态。虽然看起来重置连接应该有助于连接池和多路复用,但它会干扰 Amazon RDS 代理的内部会话状态管理。在使用 DISCARD 时,代理会在释放时固定您的客户端连接,导致降低多路复用效率。

对于您保留的应用程序级别的任何连接处理组件,需要确保它们的配置不会干扰 Amazon RDS 代理使用的连接处理逻辑。例如:

  • 跨堆栈的所有层协调池大小。如果应用程序级连接池过大(或者您的代理池过小),应用程序可能会尝试打开未配置代理进行处理的连接。这些连接在最好的情况下会遇到延迟,最坏的情况是出现拒绝错误。

  • 协调超时设置以减少连接流失并避免对连接行为的混淆。如果应用程序池保持连接活动时间为 300 秒,但代理配置为在 60 秒后关闭连接,应用程序将会看到连接过早关闭,而不是预期的行为。

其中一些架构决策和配置选择可能需要进行测试和实验。在具有多层连接池和连接管理的环境中,并不总是能够准确地预测应用程序的行为。

请参阅 配置准则 以获取常见的配置指南。