RDS的数据库独享代理提供连接池功能,您可以根据业务选择合适的连接池类型,有效解决连接数过多或短连接业务(例如PHP)频繁建立新连接导致实例负载过高的问题。

前提条件

开通独享代理

背景信息

RDS独享代理提供2种类型连接池,详细说明如下:

  • 事务级连接池(默认)

    事务级连接池主要用于减少直接连接到数据库的业务连接数,以及减少短连接场景下频繁建连带来的负载。独享代理默认使用事务级连接池,适用于总连接数比较多(如连接数上万)的场景。

    事务级连接池

    开启事务级连接池后,客户端与独享代理间可以存在上千个连接,但代理与后端数据库间可能只存在几十或几百个连接。

    独享代理本身并没有最大连接数的限制,连接数的限制主要由后端数据库中计算节点的规格决定。未开启事务级连接池时,每条由客户端发起的连接都需要在后端主节点和所有只读节点上各创建一个对应的连接。

    开启事务级连接池后,当客户端发送请求时,会先与独享代理建连,代理不会马上将其与后端数据库建连,而是先从事务级连接池里查找是否存在可用的连接(判断是否为可用连接的条件:userdbname和系统变量这3个参数值是否一致)。若不存在,代理会与数据库创建一个新连接;若存在,则从连接池里直接拿出并使用,并在当前事务结束后将该连接放回事务级连接池,方便下个请求继续使用。

    事务级连接池使用中有一些限制,请参见事务级连接池限制

  • 会话级连接池连接池

    会话级连接池适用于短连接场景。

    会话级连接池主要用于减少短连接业务频繁建立新连接带来的实例负载。当某客户端连接断开时,系统会判断当前连接是否为闲置连接,如果是闲置连接,系统会将该连接放到代理的连接池中并保留一小段时间。当客户端重新发起新连接时,若连接池中有可用的连接(命中的条件包括user、clientip和dbname等),则可直接使用,从而减少与数据库的建连开销。如果连接池内没有可用的闲置连接,则走正常连接流程,与数据库重新建立新连接。

    说明
    • 会话级连接池并不能减少数据库的并发连接数,而是通过降低应用与数据库建立连接的速率来减少MySQL主线程的开销,更好地处理业务请求。但连接池里的闲置连接会短暂占用您的连接数。
    • 会话级连接池不能解决由于存在大量慢SQL,导致的连接堆积问题,您需要先解决慢SQL问题。

注意事项

  • 当前连接池功能不支持同一账号对不同IP有不同权限,这可能会导致连接复用时权限出错。例如user@192.168.1.1设置了database_a的权限,而user@192.168.1.2没有database_a的权限,开通连接池可能会导致权限错误问题。
  • 连接池功能是指Proxy的连接池功能,不影响客户端的连接池功能,如果您的客户端已经支持连接池,则可以不使用Proxy的连接池功能。

事务级连接池限制

  • 执行以下操作时,连接将被锁定直至连接结束(即该连接不会再被放到连接池里供其它用户连接使用)。
    • 执行PREPARE语句或命令。
    • 创建临时表。
    • 修改用户变量。
    • 大报文(例如16M以上)。
    • 使用lock table。
    • 多语句。
    • 存储过程调用。
  • 不支持FOUND_ROWS、ROW_COUNT和LAST_INSERT_ID函数的调用,这些函数可以调用成功,但是无法保证调用结果的正确性。其中:
    • 1.13.11及以上的数据库代理版本支持在SELECT SQL_CALC_FOUND_ROWS * FROM t1 LIMIT *语句后直接使用SELECT FOUND_ROWS()命令。但MySQL官方已不推荐该用法,建议您将SELECT FOUND_ROWS()替换为SELECT COUNT(*) FROM tb1进行查询,详情请参见FOUND_ROWS()
    • 1.13.11及以上的数据库代理版本支持在INSERT后直接使用SELECT LAST_INSERT_ID()语句,来保证查询结果正确性。
  • 对于设置了wait_timeout的连接,wait_timeout在客户端的表现可能不会生效,因为每次请求都会从连接池中获取连接,当wait_timeout超时后,只有连接池中的后端连接会断开,而后端连接断开并不会导致客户端连接断开。
  • 除了sql_modecharacter_set_servercollation_servertime_zone这四个变量以外,如果业务依赖其他session级别的系统变量,那么需要客户端在建连之后显式执行set语句,否则连接池可能会复用系统变量已经被更改过的连接。
  • 由于连接可能会被复用,您可以使用select connection_id()查询当前连接的thread id。
  • 由于连接可能会被复用,所以show processlist显示的IP地址和端口可能和客户端实际的IP地址和端口不一致。
  • 数据库代理会将所有节点上的show processlist结果合并后返回,在事务级连接池开启后,前端连接和后端连接的thread id无法对应。这导致kill命令可能会报错,但是实际上kill命令已经正常执行成功,可再通过show processlist确定相应的连接是否断开。

如何选择连接池

您可以根据如下建议评估选择是否开启连接池以及开启何种类型的连接池:
  • 事务级连接池:若业务使用的连接数较多(如连接数需求上万)或使用的是Serverless服务(即连接数会随着业务端服务器的扩容而线性增加),且确认您的业务不涉及上述事务级连接池使用限制的场景,那么您可以选择开启事务级连接池。
  • 会话级连接池:若业务使用的纯短连接,且业务使用场景中包含上述事务级连接池使用限制的场景,那么您可以考虑开启会话级连接池。
  • 不使用:若业务使用的多为长连接且连接数较少,或者业务本身已具备较好的连接池,那么您可以不使用RDS的连接池功能。

修改连接池

  1. 进入数据库代理页面。
    1. 登录RDS管理控制台,在左侧单击实例列表,然后在上方选择地域。
      选择地域
    2. 单击目标实例ID,在左侧导航栏单击数据库代理
  2. 单击代理终端(原读写分离)页签,在目标代理终端区域中的连接池右侧选择连接池类型。
    说明 修改连接池类型仅对新连接生效。

相关API

API 描述
DescribeDBProxy 查询RDS实例的数据库独享代理详情。
DescribeDBProxyEndpoint 查询RDS实例独享代理的连接地址信息。
ModifyDBProxyEndpoint 修改RDS实例数据库独享代理的连接地址信息。