设置连接池

如果您的应用连接创建频繁(例如短连接场景)或者连接数量很大(大于MySQL数据库的连接数限制),您可以参考本文使用合适的RDS MySQL数据库代理连接池,降低应用与数据库建立连接的频率来减少MySQL数据库主线程的开销,减少数据库上的总连接数。

关于RDS数据库代理的使用问题和更多相关信息,欢迎加入用户钉钉群(106730000316)进行咨询、反馈和交流 。

选择连接池

RDS MySQL数据库代理连接池分为事务级连接池和会话级连接池,您可以按照实际使用场景选择是否使用连接池,以及使用连接池的类型:

连接池类型

使用场景

事务级连接池(推荐)

  • 业务侧多为短连接

  • 连接创建频繁

  • 连接数量很大(大于MySQL数据库的连接数限制)

以上场景下,业务不涉及事务级连接池的使用限制,建议优先选择事务级连接池。

会话级连接池

  • 业务侧多为短连接

  • 连接创建频繁

以上场景下,业务受到事务级连接池的使用限制而无法使用事务级连接池,可使用会话级连接池。

不使用连接池

  • 业务侧多为长连接

  • 连接数量很少

  • 业务侧已经使用了连接池(例如:Druid、DBCP、C3P0、HikariCP等)

连接池类型介绍

会话级连接池

应用场景

  • 业务侧多为短连接

  • 连接创建频繁

以上场景下,业务受到事务级连接池的使用限制而无法使用事务级连接池,可使用会话级连接池。

作用

降低应用与数据库建立连接的频率来减少MySQL数据库主线程的开销。

工作原理

前端连接与后端连接

在客户端(应用)与数据库建立连接时,以数据库代理为中间节点可将该连接分为前端连接(客户端与数据库代理的连接)和后端连接(数据库代理与数据库的连接)。如下图所示。

image

未开启连接池时的连接建立过程

未开启连接池时,每条由客户端发起的会话都需要创建前端连接和后端连接。会话结束后,前端连接和后端连接均断开,等到下次客户端发起会话请求时,再重新创建新的前端连接和后端连接。如下图所示。

image

使用这种建立连接的方式,每次会话都要重新建立后端连接,对数据库的主线程的开销较大。

会话级连接池工作原理

对于会话级连接池,当客户端发起的会话建立连接时,先建立前端连接,然后判断连接池中是否存在可用的后端连接:

说明

判断是否为可用连接的条件:user、clientip和dbname等参数值是否一致。

  • 若存在,则直接使用。

  • 若不存在,则与数据库建立新的后端连接。

会话结束后,前端连接断开,后端连接放入连接池,待新的会话建立连接时,可直接使用该后端连接。

这样,就降低了数据库代理与数据库建立连接的频率,从而减少了数据库主线程的开销。

连接建立的流程如下图所示。

image

对于会话级连接池,一个会话需要占用一个后端连接,直到会话结束才会释放后端连接到连接池,如下图所示。

image

使用限制

无。

注意事项

对于会话级连接池,在一个会话未结束之前,即便该会话处于闲置状态,没有事务需要处理,其后端连接也不能为其他会话使用,所以不能减少数据库的总连接数。

事务级连接池(推荐)

应用场景

  • 业务侧多为短连接

  • 连接创建频繁

  • 连接数量很大(大于MySQL数据库的连接数限制)

以上场景下,业务不涉及事务级连接池的使用限制,建议优先选择事务级连接池。

作用

  • 降低应用与数据库建立连接的频率来减少MySQL数据库主线程的开销。

  • 减少数据库上的总连接数。

工作原理

开启事务级连接池后,当客户端发起连接会话请求时,只会先与数据库代理建立前端连接,代理不会马上将其与后端数据库建立连接;当需要处理请求时,从事务级连接池里查找是否存在可用的后端连接:

说明

判断是否为可用后端连接的条件:userdbname和部分系统变量的参数值是否一致。

  • 若存在,则从连接池里直接获取后端并使用,并在当前事务结束后将该连接放回事务级连接池,方便下个请求继续使用。

  • 若不存在,代理会与数据库创建一个新的后端连接。

对于事务级连接池,在一段时间内,多个会话可共用一个后端连接。如下图所示,事务活跃的连接会占用后端连接,事务非活跃的连接不会占用后端连接。

image

这样,在一段时间内,同一个后端连接,就可以处理多个进行中的会话的事务处理请求,可以带来以下好处:

  • 减少与数据库建立连接的频率

    后端连接在一段时间内与数据库并没有断开,能够减少与数据库建立连接的频率,从而减少数据库主线程的开销。

  • 减少与数据库的总连接数

    多个进行中的会话共用了一个后端连接,避免了闲置连接(会话未结束,但前端连接为非活跃状态)对后端连接资源的占用,减少了数据库上的总连接数。

说明

数据库代理本身并没有最大连接数的限制,连接数的限制是由后端数据库的规格决定。

使用限制

  • 执行以下操作时,连接将被锁定直至连接结束(即该连接不会再被放到连接池里供其他用户连接使用):

    • 执行PREPARE语句或命令。

    • 创建临时表。

    • 修改用户变量。

    • 大报文(例如16 MB以上)。

    • 使用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或者SQL洞察显示的IP地址和端口可能和客户端实际的IP地址和端口不一致。

  • 数据库代理会将所有节点上的show processlist结果合并后返回,在事务级连接池开启后,前端连接和后端连接的thread id无法对应。这导致kill命令可能会报错,但是实际上kill命令已经正常执行成功,可再通过show processlist确定相应的连接是否断开。

设置连接池

前提条件

已开通数据库代理

注意事项

  • 当前连接池功能不支持同一个账号对不同IP有不同的权限。如果您为同一个账号的不同IP设置了不同的库或者表权限,开通连接池可能会导致权限错误问题。例如,user@192.xx.xx.1设置了database_a的权限,而user@192.xx.xx.2没有database_a的权限,可能会导致连接复用时权限出错。

  • 本文介绍的连接池功能是指RDS MySQL数据库代理的连接池功能,不影响客户端的连接池功能,如果您的客户端已经支持连接池,则可以不使用数据库代理的连接池功能。

  • 连接池不能解决由于存在大量慢SQL,导致的连接堆积问题,建议自行优化SQL,或者在MySQL侧排查慢的原因。

  • 当数据库代理内核小版本低于2.9.1时,读写属性为只读的连接地址不支持设置连接池。当数据库代理内核小版本为2.9.1及以上时,读写属性为读写和只读的连接地址均支持设置连接池。

操作步骤

  1. 访问RDS实例列表,在上方选择地域,然后单击目标实例ID。

  2. 在左侧导航栏,单击数据库代理

  3. 连接信息区域,您可以通过两种方法开启连接池:

    说明
    • 默认关闭连接池。

    • 修改连接池类型后,仅对新连接生效。

    • 方法一:将鼠标置于代理连接地址(终端)ID右侧的image.png图标,在弹出的对话框中单击开启事务级连接池开启会话级连接池,然后在弹出的对话框中单击确定

      image.png

    • 方法二:在目标代理连接地址操作列,单击修改配置,在弹出的对话框中,在连接池右侧选中目标连接池类型,即开启了对应类型的连接池。

      说明

      如果原来已经开启了某类连接池,重新选择连接池类型,可修改类型。

      image.png

相关API

API

描述

DescribeDBProxy

查询RDS实例的数据库代理详情。

DescribeDBProxyEndpoint

查询RDS实例数据库代理的连接地址信息。

ModifyDBProxyEndpoint

修改RDS实例数据库代理连接地址访问策略。

相关概念

  • 短连接:指仅在短时间保持的连接。例如PHP应用程序,客户端打开一个连接,执行一个简单的查询,然后关闭连接。优点是不需要长期占用连接通道,缺点是每次发送业务都要建一次连接,建立连接耗费MySQL数据库主线程的开销大。

  • 长连接:指长时间保持的连接。例如,可能有一个Web服务器或应用程序服务器打开许多到MySQL服务器的连接,并保持它们打开,直到客户端(Web/Application服务器)停止,可能要持续数月。优点是与数据库建立连接的次数相对较少,耗费MySQL数据库主线程的开销小。缺点是需要长期占用连接通道。

常见问题

Q:连接数达到多少,建议开启连接池?

A:连接数如果可能超过MySQL数据库的连接数上限, 建议开启事务级连接池。

Q:连接池的连接保持时间是多少?

A:10秒。

Q:使用连接池对实例性能有影响吗?

A:使用连接池后,短连接场景下,实例性能会有10%左右的提升。

Q:事务级连接池和会话级连接池的作用有何差异?

A:事务级连接池不仅可以减少MySQL数据库主线程的开销,还可以减少数据库上的总连接数。

会话级连接池只能减少MySQL数据库主线程的开销,不能减少数据库上的总连接数。

Q:事务级连接池和会话级连接池在工作原理上有何不同?

A:

连接池类型

会话是否可以共用后端连接

取后端连接的时机

把后端连接放回连接池的时机

会话与后端连接的映射关系

事务级

处理事务时

处理完一个事务(此时会话可能没结束)

N:1

会话级

建立会话时

会话结束

N:N

Q:数据库代理出现连接断开的问题,是否因为应用和数据库代理都用了连接池的功能?

A:连接断开的原因很多,需要根据具体情况分析,不一定是因为应用和数据库代理都用了连接池的功能。