网易开源 lb-driver:OceanBase OBProxy 驱动层负载均衡实践

前言

在企业级分布式数据库落地场景中,OceanBase 以高可用、高吞吐、水平弹性扩缩容的能力,成为金融、社交、电商等核心业务的首选分布式数据库。网易云信在架构升级迭代过程中,也选择了 OceanBase 作为核心业务的数据库,代替内部的分库分表中间件 DDB。

OceanBase 典型架构依赖 OBProxy 代理集群承接前端业务连接、路由 SQL 请求、管控分区读写。传统接入方案里,业务往往依赖 SLB / NLB / 四层负载均衡做 OBProxy 集群流量入口。在从 DDB 切换到 OceanBase 后,我们也发现了部分业务 SQL 的 RT 有增长,分析后认为除了 OceanBase 的 Paxos 强一致性带来的延迟增加之外,网络上多了负载均衡器的一跳也是不可忽视的。

痛点

主流 OceanBase 业务接入架构:应用服务 → 数据库连接池 → SLB负载均衡 → OBProxy集群 → OBServer集群

这套标准架构一般来说没有什么问题,但是在高并发高流量的场景下,也有一些明显的问题:

  • 链路冗余,时延抬高。额外经过 SLB 转发,网络链路多一跳,单次 SQL 请求 RT 增加(一般0.2ms左右),高并发峰值场景时延放大会更突出。
  • 负载均衡粒度粗糙。SLB是标准的四层负载均衡器,并不感知业务协议,只能基于连接做负载均衡,可能出现OBProxy负载不均衡的问题。
  • 性能瓶颈。所有数据库流量收敛到 SLB 集群,大促、峰值流量下容易出现连接打满、带宽瓶颈。
  • 节点扩缩容运维不够丝滑。数据库连接一般都为长连接,上下线 OBProxy 节点或做 OBProxy 节点更新时周期较长,有时还需业务配合重启。
  • 故障感知能力。SLB 等四层负载均衡,健康检查只支持 TCP 端口连通性,无法判定端口通但进程僵死无法处理 SQL 等异常情况。

客户端负载均衡方案(lb-driver)

源于 DDB-lbd

实际上我们原先使用的分库分表中间件 DDB 本身就支持 lbd,架构:应用服务 → 数据库连接池 → LBD → QS集群 → MySQL集群。可以看到 DDB 在架构上和 OceanBase 还是有相通的地方。但 ddb-lbd 在实现上和 DDB 耦合在了一起,因此无法直接复用于 OceanBase。所以我们决定参考 ddb-lbd 的设计思路,取长补短,重新实现一个更通用的 lb-driver 来适配 OceanBase 的业务场景。

负载均衡原理

在 SLB 四层负载均衡器的模式下,负载均衡策略显然是面向连接的。而当我们将负载均衡策略下沉到 driver 层,我们就可以做得更多。在 lb-driver 的实现中,我们基于 JDBC 的 Statement 粒度来做负载均衡——你可以类比为 nginx 在七层代理场景下基于 http 单个请求的粒度来做请求分发。

健康检查和故障节点自动剔除

lb-driver 会自动探测所有的 OBProxy 节点,定时发送 select 1 的业务心跳来判断节点是否健康。此外也会监控业务 sql 的执行情况,只要出现特定的异常(如建连超时,或者 OceanBase 中的 -9000 到 -8000 的错误码等等),也会立即把连接设置为 unhealthy 并在异常数量达到阈值后直接屏蔽相关节点。

节点的快速扩缩容

支持在地址串中直接配置所有的 OBProxy 节点列表,也支持通过一个独立的 config-server 服务去动态获取 OBProxy 节点列表。config-server 可以基于 etcd 或者 nacos 来进行动态配置,从而可以在不重启业务的情况下动态扩缩容 OBProxy 集群。

业务无侵入

lb-driver 仅依赖 slf4j 和 mysql-connector-java。你仅需在业务工程中引入 lb-driver 的依赖,并把 com.mysql.jdbc.Driver 替换为 com.netease.nim.lbd.LBDriver 即可,不需要任何业务代码的改造。

整体架构

lb-driver 包括如下几个组件:独立部署的 config-server、SqlProxyProvider(提供 obproxy 的节点列表)、ConnectionManager(管理连接生命周期和 statement 级别的负载均衡策略)、balance 和 detect 两个定时任务(用于连接层面的负载均衡和健康检查)。

落地实践

目前网易云信的所有线上 OceanBase 集群均已迁移到 lb-driver 模式,其他部门也在陆陆续续往 lbd 模式迁移。

展望

lb-driver 目前已经在 github 开源:https://github.com/netease-im/lb-driver(欢迎 star 和 fork,有任何问题也欢迎 issue)。我们是 OceanBase 社区版的受益者,而 lb-driver 作为 OceanBase 开源生态的一部分,我们也期望可以回馈开源社区,大家一起共建共创~