集群代理模式连接池功能最佳实践

集群代理模式的连接池功能,通过池化和复用代理(Proxy)到数据库(DB)的连接,解决因特定状态化命令导致的后端 DB 连接数耗尽问题,以保障云数据库 Tair(兼容 Redis)实例的稳定性。

业务场景说明

云原生集群实例代理模式,常规命令通过共享连接转发,客户端连接数的增加不影响后端 DB 的连接数。当业务逻辑包含特定状态化命令时,Proxy 与数据节点之间的连接会从“共享模式”转为“独享模式”。

在独享模式下,每个客户端连接将在数据节点上建立一个对应的独享连接。这会导致在高并发场景下,数据节点的连接数随客户端连接数线性增长,进而触发 max number of clients reached 错误,导致服务中断。

在使用 watch 或阻塞类请求时,通过扩容增加分片数并不能解决单个分片上连接数过高的问题。

触发“独享模式”的命令主要包括:

  • 事务命令: MULTI/EXEC (在 WATCH 之后)

  • 阻塞命令: BLPOP, BRPOP, BRPOPLPUSH, XREAD ... BLOCK ...

连接池功能通过池化和复用 Proxy 到数据节点的独享连接,降低数据节点上的连接数,从而避免因连接数超限导致的请求失败。

方案架构

连接池功能在每个 Proxy 子实例上独立运行,为该 Proxy 到每个数据节点的连接维护一个专用的连接池。

image

示例说明:

在未使用连接池时,客户端与Proxy之间的每个连接都会在后端访问的每个数据分片上建立一个独立连接。例如,10个客户端连接都访问5个分片时,将导致总共 10 × 5 = 50 个连接。

而当开启连接池后,代理会为每个数据分片维护一个有限的连接池,客户端请求会复用这些池中的连接。这显著减少了实际建立的数据库连接数。例如,相同的10个客户端连接,可能只需每个分片维护2个连接池中的连接,总计仅需 2 × 5 = 10 个连接。

工作流程:

  1. 当客户端连接(Client Conn)发起独享模式请求时,Proxy 节点将从对应的数据分片连接池中获取一个空闲连接。

  2. 池命中:如果池中有空闲连接,Proxy 立即将该连接绑定到客户端连接,用于转发请求。请求完成后,连接被解绑并返回连接池,以供其他客户端复用。

  3. 池未命中:如果池中无空闲连接,Proxy 将在池中创建一个新连接。请求完成后

    1. 如果池内总连接数未达到上限(private_conn_pool_max_idle_per_db),此连接进入池内。

    2. 如果池内总连接数已达到上限,此连接会立刻释放(短连接模式)。

这种优化极大地减轻了数据库的连接管理负担,减少了资源开销,提高了数据库的稳定性和吞吐量。

适用范围

实例需满足以下条件:

启用连接池功能

通过修改实例参数开启连接池功能。此操作支持热更新,无需重启实例,对业务无影响。

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

  2. 在左侧导航栏中,单击参数设置

  3. 在参数列表中找到 private_conn_pool_enabled,单击其右侧的修改

  4. 在弹出的对话框中,将参数值修改为 1,然后单击确定

后续可通过云监控控制台找到对应实例,查看基础监控项ProxyDB连接数,对比开启前后数据变化。

配置详解与调优指南

配置名

含义

默认值

取值范围

private_conn_pool_enabled

连接池功能开关。1 为开启,0 为关闭。

0

[0|1]

private_conn_idle_time_sec

池中空闲连接的存活时间(秒)。超过此时间未被使用的空闲连接将被关闭。值为 0 表示立即关闭。

60

[0-4294967295]

private_conn_pool_max_idle_per_db

每个 Proxy 节点为每个数据节点维护的最大空闲连接数。当一个连接使用完毕后,如果池中空闲连接数已达到此上限,该连接将被关闭而不是返回连接池。

1000

[0-4294967295]

private_conn_pool_min_idle_per_db

每个 Proxy 节点为每个数据节点维护的最小空闲连接数。池中空闲连接数低于此值时,即使达到 private_conn_idle_time_sec 也不会被回收。

0

[0-4294967295]

场景化调优建议

  • 通用场景:建议保持默认配置,适用于大多数业务。

  • 高并发短事务场景(例如:秒杀业务)

    • 特征:连接占用时间短,借还操作频繁。

    • 建议private_conn_pool_max_idle_per_db 建议设置为能够覆盖业务高峰期并发请求数的值,以最大化连接复用率,避免降级为短连接。private_conn_idle_time_sec 建议使用默认值或适当缩短,以在流量低谷时更快释放资源。

  • 长阻塞业务场景(例如:队列消费者使用 )

    • 特征:连接长时间被占用,不归还到池中。

    • 建议:建议调高 private_conn_pool_max_idle_per_db 以容纳并发的消费者数量。建议将 private_conn_pool_min_idle_per_db 设置为略高于平均并发数的值,以“预热”连接,减少新消费者启动时的建连延迟。

  • 实例规格较低或内存敏感场景

    • 特征:需要严格控制内存占用。

    • 建议:建议调低 private_conn_pool_max_idle_per_dbprivate_conn_pool_min_idle_per_db。此操作会牺牲少量性能(可能增加短连接创建的几率),以节省数据节点的内存资源。

注意事项

  • 设置合理的private_conn_pool_min_idle_per_db

    每个空闲连接会在后端 DB 节点上消耗一定的内存资源。在多分片、多 Proxy 节点的实例中,过高的 private_conn_pool_min_idle_per_db 设置可能导致较高的内存占用。

  • 避免不必要的 DB 上下文切换

    当连接池中的连接被复用于访问不同 DB 索引的客户端时,Proxy 需要执行 SELECT 命令来切换上下文,此操作会增加 DB 的负载和请求延迟。建议在应用设计上,确保所有客户端使用相同的 DB 索引(通常是 DB 0)。

  • 不适用于发布订阅命令

    连接池功能不适用于 SUBSCRIBE/PSUBSCRIBE 等发布订阅命令。这些命令会永久占用连接,因此连接不会被池化管理。

相关文档