写点什么

使用 TiDB 时的连接池和负载均衡器配置策略

  • 2022 年 7 月 11 日
  • 本文字数:3487 字

    阅读完需:约 11 分钟

作者: Gin 原文来源:https://tidb.net/blog/55452f4f


【是否原创】是


【首发渠道】TiDB 社区


【正文】

一、背景

TiDB 计算层 —— tidb-server 的无状态特点、以及事务状态由存储组件(TiKV)分布式管理的特性不同于一般单机数据库或具备 GTM 的分布式数据库,可以使用常常被部署在应用前端的负载均衡器来实现 tidb-server 的负载均衡,同时也使 TiDB 计算层具备了高可用能力(高可用性详见 TiDB 集群可用性详解及 TiKV Label 规划 - Google 文档)。


理论上讲,TiDB 支持所有 4 层(TCP/IP)负载均衡器(LB - Load Balancer),并支持负载均衡器上的 7 层 MySQL 协议探活机制。


常见 4 层负载均衡器包括:


  • 硬件:F5、A10 等

  • 软件:HAProxy、Nginx、LVS(v1.9 及更高版本)、各种云上 ELB、NLB 等


连接池用于维护应用到数据库之间的长连接,避免了每次请求都要建立新的连接而造成的时间开销。常见的 Java 应用连接池:


  • Druid:阿里开源的数据库连接池,主要特点是功能全面, 性能和稳定性也都不错,被国内用户广泛使用。

  • C3P0:早期一款数据库连接池产品, Hibernate 将其作为内置的数据库连接池,简单易用稳定性好,但性能差,架构复杂。

  • DBCP:2014 年 DBCP 更新 2.0,性能尚可,但相比于竞品没有明显优势。

  • HikariCP:Springboot2.+ 官方默认的数据库连接池,性能强劲,稳定性好。

  • IBM WAS 内置连接池,传统金融用户广泛使用。

  • Oracle Weblogic 内置连接池,传统金融用户广泛使用。

二、负载算法

如上一章所讲,应通过长连接的方式来访问数据库以保障性能,因此建议使用最小连接数(least connection)的负载算法配置 LB,使连接数最少的服务器优先接收连接。

三、空闲连接超时配置策略

应用通过连接池维护应用到 LB 之间的长连接,同样的,LB 通过长连接和 TiDB 进行交互,而应用连接池和 LB 这两者都具备自动清理超时空闲连接的机制(idle timeout),为了避免出现空闲连接被“多次”清理的问题,需要考虑整体的配置策略。


根据过往的客户项目经验,我们建议将空闲连接超时交给应用连接池来处理,将 LB 的空闲连接超时配置为无限制或足够长的时间(比如一年),这样建议的原因是应用连接池更贴近应用程序和业务,方便管理连接和排查问题。


一定要避免将 LB 的空闲连接超时配置的比连接池更短,这将使 LB 提前杀死连接而导致连接池不知情。

四、探活

探活分为 4 层探活(ip:port)和 7 层探活(SQL 语句探活),主流的 LB 和连接池都支持这两种探活机制,4 层探活为固有能力,7 层探活一般需要额外配置。


就探活频率来说,LB 的探活频率较高些,而连接池一般支持在创建连接、关闭连接、连接空闲时进行探活。


以 Druid 连接池为例,7 层探活配置如下:


# validation-query 设置探活语句,当不设置时,下面三个参数将不生效spring.datasource.druid.validation-query = select 1# test-on-borrow 为 true 时,在创建连接时探活,影响性能,一般建议关闭spring.datasource.druid.test-on-borrow = false# test-on-return 为 true 时,在关闭连接时探活,影响性能,一般建议关闭spring.datasource.druid.test-on-return = false# test-while-idle 为 true 时,在连接空闲时探活,对性能基本无影响,建议开启spring.datasource.druid.test-while-idle = true
复制代码


除了以上配置项外,注意还需要在应用代码中加入:


System.setProperty("druid.mysql.usePingMethod","false");


这条代码的作用是关闭 ping 探活方式,让 validation-query 能够生效,1.x 版本以上可用。


以 HAProxy 负载均衡器为例,7 层探活配置如下:


option mysql-check user haproxy post-41 #对性能基本无影响,建议开启


下表展示了在不同故障下,配置了 7 层探活的 LB 和连接池的响应。



表 1:故障下 LB 与连接池的响应

五、负载均衡器 IP 透传

应用服务通过 LB 连接到 TiDB 时,其原本的服务器 IP 会被屏蔽掉,show processlist


中只能看到 LB 的 IP,不方便问题排查和定位。而通过配置负载均衡器 IP 透传策略,可以使 TiDB 的诊断日志中记录原始请求发起位置的 IP 地址,方便问题的排查。


HAProxy


  1. 在节点条目上增加 send-proxy 配置项

  2. server tidb1 10.0.1.4:4000 send-proxy

  3. 调整 TiDB 启动脚本,增加 proxy 协议配置项 *

  4. –proxy-protocol-networks


* 注意:开启 proxy 协议支持后,tidb-server 将无法直连,只能通过 HAProxy 连接。


LVS 或其他支持 TOA(TcpOptionAddress)的 LB


调整 TiDB 配置项 enable-tcp4-only(从 v5.0 版本开始引入)值为 true,这是因为 LVS 的 TOA 模块可以通过 TCP4 协议从 TCP 头部信息中解析出客户端的真实 IP。

六、连接池配置参考

springboot-druid:


# jdbc urlspring.datasource.druid.url=JDBC:mysql://{TiDBIP}:{TiDBPort}/{DBName}?characterEncoding=utf8&useSSL=false&useServerPrepStmts=true&prepStmtCacheSqlLimit=10000000000&useConfigs=maxPerformance&rewriteBatchedStatements=true&defaultfetchsize=-2147483648# 用户名spring.datasource.druid.username=root# 密码spring.datasource.druid.password=root# 驱动spring.datasource.druid.driver-class-name=com.mysql.jdbc.Driver# 初始化时建立物理连接的个数spring.datasource.druid.initial-size=5# 最大连接池数量spring.datasource.druid.max-active=30# 最小连接池数量spring.datasource.druid.min-idle=5# 获取连接时最大等待时间,单位毫秒spring.datasource.druid.max-wait=60000# 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒spring.datasource.druid.time-between-eviction-runs-millis=60000# 连接保持空闲而不被驱逐的最小时间spring.datasource.druid.min-evictable-idle-time-millis=300000# 用来检测连接是否有效的sql,要求是一个查询语句spring.datasource.druid.validation-query=SELECT 1 # 建议配置为true,不影响性能,并且保证安全性。申请连接的时候检测,如果空闲时间大于timeBetweenEvictionRunsMillis,执行validationQuery检测连接是否有效。spring.datasource.druid.test-while-idle=true# 申请连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能。spring.datasource.druid.test-on-borrow=false# 归还连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能。spring.datasource.druid.test-on-return=false# 是否缓存preparedStatement,也就是PSCache。PSCache对支持游标的数据库性能提升巨大,比如说oracle。在mysql下建议关闭。spring.datasource.druid.pool-prepared-statements=true# 要启用PSCache,必须配置大于0,当大于0时,poolPreparedStatements自动触发修改为true。spring.datasource.druid.max-pool-prepared-statement-per-connection-size=50# 配置监控统计拦截的filters,去掉后监控界面sql无法统计spring.datasource.druid.filters=stat,wall# 通过connectProperties属性来打开mergeSql功能;慢SQL记录spring.datasource.druid.connection-properties=druid.stat.mergeSql=true;druid.stat.slowSqlMillis=500# 合并多个DruidDataSource的监控数据spring.datasource.druid.use-global-data-source-stat=true
复制代码

七、负载均衡器配置参考

HAProxy


global        log 127.0.0.1   local2        maxconn 4096        user haproxy        group haproxy        chroot /var/lib/haproxy        daemon        pidfile /var/run/haproxy.pid        stats socket /var/run/haproxy.sock    # Make sock file for haproxy        nbthread 40    # 启动 n(以 40 为例) 个线程并发转发
defaults log global mode http option tcplog option dontlognull retries 3 option redispatch maxconn 1024 timeout connect 500000s timeout client 500000s timeout server 500000s
listen tidb_cluster bind 0.0.0.0:8001 # 真正的 proxy 名以及接受服务的地址 mode tcp balance leastconn # 这个方法最适用于数据库 option mysql-check user haproxy post-41 # 7层探活 server tidb1 172.16.4.81:4000 check server tidb2 172.16.4.81:4001 check server tidb3 172.16.4.88:4000 check server tidb4 172.16.4.88:4001 check server tidb5 172.16.4.91:4000 check
#IP 透传 #server tidb1 172.16.4.81:4000 check send-proxy
复制代码


发布于: 刚刚阅读数: 2
用户头像

TiDB 社区官网:https://tidb.net/ 2021.12.15 加入

TiDB 社区干货传送门是由 TiDB 社区中布道师组委会自发组织的 TiDB 社区优质内容对外宣布的栏目,旨在加深 TiDBer 之间的交流和学习。一起构建有爱、互助、共创共建的 TiDB 社区 https://tidb.net/

评论

发布
暂无评论
使用 TiDB 时的连接池和负载均衡器配置策略_TiDB 社区干货传送门_InfoQ写作社区