背景
tidb-loadbalance 是用于 Java 应用客户端的负载均衡组件,fork 自 tidb-incubator 的 TiBigData 项目,目前属于官方维护的 JDBC Wrapper 产品。主要的技术特性有:
- 读取系统表自动维护 TiDB Server 的节点信息(要求节点注册 IP 客户端可访问)。实现了轮询、随机、权重负载均衡策略,具有服务端连接节点的切换能力。
- 客户端实现分发连接,客户端和 TiDB Server 使用 JDBC 直连的方式。
产品配置和功能测试
tidb-loadbalance 支持的均衡策略
- 轮询策略 tidb.jdbc.url-mapper = roundrobin
JDBC URL 需要只需要配置 一个 TiDB Server,自动使用 tidb 集群系统表内的 tidb-server 注册的 IP 地址进行负载均衡,每个客户端各自轮流使用 TiDB Server 清单中的实例。
jdbc:tidb://{ip}:{port}/db?tidb.jdbc.url-mapper=roundrobin
该策略为默认策略,可以不用配置 tidb.jdbc.url-mapper=roundrobin
- 随机策略 tidb.jdbc.url-mapper = random
同轮询策略一样,JDBC URL 需要只需要配置 一个 TiDB Server,每个客户端随机使用 TiDB Server 清单中的实例。
jdbc:tidb://{ip}:{port}/db?tidb.jdbc.url-mapper=random
- 权重策略 tidb.jdbc.url-mapper = weight
在此模式下,JDBC URL 需要指定所有 TiDB Server 的{ip} {port} {weight}
属性,每个客户端根据权重使用 TiDB Server 清单中的实例。
jdbc:tidb://{ip1}:{port1}:{weight1},{ip2}:{port2}:{weight2},{ip3}:{port3}:{weight3}/db?tidb.jdbc.url-mapper=weight
权重策略提供了手工指定清单的能力,更为灵活,可以适用于业务和 tidb-server 注册于不同网段,或者 tidb-server 按功能不同分组的场景。
生产环境请参考官方文档
https://docs.pingcap.com/zh/tidb/stable/dev-guide-choose-driver-or-orm#java-%E5%AE%A2%E6%88%B7%E7%AB%AF%E8%B4%9F%E8%BD%BD%E5%9D%87%E8%A1%A1
测试过程
环境信息:
TiDB: V6.1.1
tidb-loadbalance: 0.0.6
- 应用部署 tidb-loadbalance 驱动并配置
默认情况下,tidb-loadbalance 驱动会自动使用 tidb 集群系统表内的 tidb-server 注册的 IP 地址进行负载均衡。在本例中,由于数据库服务器配置双网卡,tiup 工具部署的集群节点 IP 所在的内网(192.168.4.x)和外部客户端连接的 tidb-server 使用的网络(10.x.x.x)分属于不同网络,不能直接使用系统表内的地址访问。
手工用权重负载的方式在 jdbc url 中写明集群可用节点的 IP,应用框架中使用的 url 如下:
datasource:
url: jdbc:tidb://10.x.x.21:4000:10,10.x.x.21:4001:10,10.x.x.21:4002:10,10.x.x.22:4000:10,10.x.x.22:4001:10,10.x.x.22:4002:10,10.x.x.22:4003:10,10.x.x.23:4000:10,10.x.x.23:4001:10,10.x.x.23:4002:10,10.x.x.23:4003:10,10.x.x.24:4000:10,10.x.x.24:4001:10,10.x.x.24:4002:10,10.x.x.24:4003:10/db?tidb.discovery=false&tidb.jdbc.url-mapper=weight&characterEncoding=utf8&useSSL=false&useServerPrepStmts=true&cachePrepStmts=true&prepStmtCacheSqlLimit=10000&prepStmtCacheSize=1000&useConfigs=maxPerformance&rewriteBatchedStatements=true
username: user
password: user
driverClassName: com.tidb.jdbc.Driver
- 应用发起并发
每个 tidb-server 实例平均有 27 个左右的连接,数据库总连接409个。
- 关闭 192.168.4.103 和 104 上的所有 tidb-server
指定实例方式进行关闭操作,16 个 tidb-server 减少一半。
tiup cluster stop tidb-h -N 192.168.4.103:4000,192.168.4.103:4001,192.168.4.103:4002,192.168.4.103:4003,192.168.4.104:4000,192.168.4.104:4001,192.168.4.104:4002,192.168.4.104:4003
关闭实例的数据库连接降为 0,剩余可用节点上升一倍,总连接数大致不变。
关闭节点上现有连接的业务会报错应用侧出现 jdbc.exception 相关报错,持续时间约 80 秒。
- 增加应用并发并查看新增连接的分配情况
应用并发压力增加后数据库总连接数增加到 569,应用侧无报错。新增连接都分配在目前可用的 192.168.4.101/102 服务器 tidb-server 实例上,但新增连接不是很均匀。
- 恢复关闭的 tidb-server 实例
指定实例方式进行启动操作,恢复 16 个 tidb-server。
192.168.4.103/104 服务器 tidb-server 实例出现少量新增连接,应用侧无报错。
- 再次增加应用并发并查看新增连接的分配情况
应用并发压力增加后数据库总连接数增加到 775,应用侧无报错。新增连接中的部分连接分配到新的 192.168.4.103/104 服务器上的 tidb-server 实例,但是新增连接不均匀。
- 重启应用后并发所有连接分配均衡,与第 2 步情况一致。
测试结论
tidb-loadbalance 的优点:
- 具备负载均衡和高可用能力,部分 tidb-server 异常后,新增连接请求自动转移至剩余 tidb-server。
- 减少专用节点的资源要求,消除转发的网络延迟,性能更好。相较于 jdbc loadbalance,具有高可用、策略灵活、自维护等优势。同时,JDBC 直连的方式能让 TiDB Server 直接看见客户端 IP 地址。
tidb-loadbalance 的缺点:
- 只能用于 Java 应用,无法覆盖 C 或者 go 等其他语言的应用场景。
- 客户端的负载均衡缺少对全局 tidb-server 的负载感知能力,如:连接池已经建立的长连接的数量,所以不能使用更推荐的最少连接策略。在 0.0.7 的版本中,会提供全局连接的平衡能力。
- 维护操作需要在应用侧操作,比如修改 url 中服务器的权重,应用节点较多的情况下需要应用侧有全局节点配置的集中管理能力。
可以看出,tidb-loadbalance 适用的场景是 Java 应用,有应用平台的分发管理能力。
附:Jmeter 的 Loadbalance 配置
在 业务 POC 的过程中,经常会使用 Jmeter 工具进行压测,可以利用 Loadbalance 实现负载均衡操作。安装的简要步骤如下:
- 将 tidb-loadbalance 的驱动包复制到 Jmeter 的安装目录下。
- 在 Jmeter 的连接池配置 jdbc:tidb 的 url。
注意:Jmeter 的 jdbc 连接池参数中,Max Number of Connections 连接数不要配置 0,应该配置成和压测并发数一致,如上图中的 50。因为 Jmeter 使用 tomcat 连接池,如果配置为 0,每次按需去创建连接,不保留之前状态,loadbalance v0.0.6 默认 round-robin 的均衡策略情况下,会导致每次都取第一个节点,导致无法自动负载均衡。如果配置为 50,压测并发数使用 50 时,就会一次创建 50 个链接,基于 round-robin 的策略可达到连接均衡的效果,预计会在 loadbalance v0.0.7 版本解决该问题。可选的另一种规避方案是使用 random 策略。