NVIDIA 初创加速计划,免费加速您的创业启动 了解详情
写点什么

MySQL-JDBC Loadbalance 深入解析

  • 2019-10-21
  • 本文字数:3074 字

    阅读完需:约 10 分钟

MySQL-JDBC Loadbalance深入解析

公司的整个电商系统搭建在华为云上,根据老总的估计,上线 3 个月之后日订单量会达到百万级别,保守估计 3 个月之后总订单个数预计会有 5 千万。MySQL 单表达到千万级别,就会出现明显的性能问题。


根据如此规模的数据,当时考虑了 2 套解决方案:


方案一


在业务上根据用户 ID 做拆分,将数据打散放在 5 台 32U128G 的华为云 RDS 上边


方案二


直接使用华为云的分布式数据库中间件 DDM


方案一的好处是,分片算法全部在业务上实现,整个方案都在自己的控制下。后续问题定位,方案修改都会好很多;坏处是,整个方案需要业务代码支撑,访问到做了拆分的数据都需要做特殊处理,代价还是比较大的,而且对开发人员的能力要求很高。后续运维的工作也比较大。


方案二的好处是,直接使用云服务后续不需要担心运维的事情,另外 DDM 从中间件层屏蔽了分库分表的具体实现,业务可以当做单库来操作,易用性以及对代码的要求、对开发人员的要求都会低了很多。缺点就是,使用了 DDM 之后,对华为云的粘性会大很多。


综合考虑了两个方案的优缺点,最终选择了方案二,主要是基于对华为云技术能力和后续蓬勃发展的信心。


对 DDM 做了一定的调研,的确是一个非常不错的分库分表服务。支持超大规模数据,10 备于单机数据库的超强性能,百万并发,读写分离,支持平滑扩容等等。。。优点数不胜数~


搭建到华为云之后,一直平稳运行,但是前阵子出了个奇怪的问题,在 DDM 技术专家的协助下,很快定位了出来,结果是 MySQL-JDBC 的一个 bug 导致。作为一个具有打破砂锅问到底、不破楼兰誓不还的程序员,决定对 MySQL 的相关参数做个详细的分析,免得从一个坑里边爬出来又进了另外一个。

Loadbalance 模式说明

为了提供高性能,百万并发,DDM 自身是以无状态的集群形式对外提供的。内部怎么做的我们不清楚,能看到的是,每个 DDM 提供了多个访问地址,每个库的访问 url 类似于:jdbc:mysql:loadbalance://192.168.0.35:5066,192.168.0.192:5066,192.168.0.175:5066,192.168.0.139:5066/orderdb?loadBalanceAutoCommitStatementThreshold=5


从访问的 url 看,内部应该是多台 DDM 节点的,实际上从我们测试的情况看,访问任何一台的效果都是一样的。猜测,内部的交互应该是类似如下图的:



跟 DDM 的技术专家求证,的确是如此的,心里有点小得意~~


我们的代码全部是 java 的代码,连接池用的是 druid,根据 DDM 的指导,将 url 配置好就能正常访问了。感觉关健的就在 loadbalance 这个,应该是告诉了驱动,通过负载均衡方式访问 DDM。在网上查了下,这种方式是直接在驱动层面做的负载均衡,相比通过负载均衡器的方式,少了一次网络转发,怪不得效率会这么高。不过,APP 到底是访问哪个 DDM,内部机制是什么样子的?这些在网上查了下,都是语焉不详,没办法只好从 MySQL JDBC 的源码入手了。


驱动的源码是托管在 github 上,我们当前用的是 DDM 推荐的 5.1.44 版本的:https://github.com/mysql/mysql-connector-j/tree/5.1.44


核心的就是几个 Loadbalance 开头的类:



代码比较多,其他的就不多说了,最关键的就是下边这块代码:


LoadBalancedConnectionProxy.java 类的 pickNewConnection()函数:


这个函数在创建连接对象、一个事务提交或者回滚都会调用,作用就是轮换下一个 DDM 节点。这块代码的逻辑就是,根据一定的负载均衡策略挑选一个节点的连接,做个基本的连接有效性探测,然后将当前连接的状态同步到新连接(见 Table 2 MultiHostConnectionProxy.syncSessionState())。同步完毕,就把当前使用的连接设置为新挑选的连接。如果所有的连接都不可用,就把当前状态设置为了 Closed 状态。看着快代码,感觉 MySQL 的有些代码也不严谨,比如如果在获取新连接的时候,如果抛了 SQLException 出来,这个异常就直接被吃掉了,不会抛出去,也不会有任何信息记录下来,这个对后续的问题定位还是很不方便的,不知道是出于什么考虑的。


Table 1 LoadBalancedConnectionProxy.pickNewConnection()   synchronized void pickNewConnection() throws SQLException {       if (this.isClosed && this.closedExplicitly) {           return;       }       if (this.currentConnection == null) { // startup           this.currentConnection = this.balancer.pickConnection(this, Collections.unmodifiableList(this.hostList),                   Collections.unmodifiableMap(this.liveConnections), this.responseTimes.clone(), this.retriesAllDown);           return;       }       if (this.currentConnection.isClosed()) {           invalidateCurrentConnection();       }       int pingTimeout = this.currentConnection.getLoadBalancePingTimeout();       boolean pingBeforeReturn = this.currentConnection.getLoadBalanceValidateConnectionOnSwapServer();       for (int hostsTried = 0, hostsToTry = this.hostList.size(); hostsTried < hostsToTry; hostsTried++) {           ConnectionImpl newConn = null;           try {               newConn = this.balancer.pickConnection(this, Collections.unmodifiableList(this.hostList), Collections.unmodifiableMap(this.liveConnections), this.responseTimes.clone(), this.retriesAllDown);               if (this.currentConnection != null) {                   if (pingBeforeReturn) {                       if (pingTimeout == 0) {                           newConn.ping();                       } else {                           newConn.pingInternal(true, pingTimeout);                       }                   }                   syncSessionState(this.currentConnection, newConn);
} this.currentConnection = newConn; return; } catch (SQLException e) { if (shouldExceptionTriggerConnectionSwitch(e) && newConn != null) { // connection error, close up shop on current connection invalidateConnection(newConn); } } } // no hosts available to swap connection to, close up. this.isClosed = true; this.closedReason = "Connection closed after inability to pick valid new connection during load-balance."; }


Table 2 MultiHostConnectionProxy.syncSessionState() static void syncSessionState(Connection source, Connection target, boolean readOnly) throws SQLException { if (target != null) { target.setReadOnly(readOnly); } if (source == null || target == null) { return; }target.setAutoCommit(source.getAutoCommit()); target.setCatalog(source.getCatalog()); target.setTransactionIsolation(source.getTransactionIsolation()); target.setSessionMaxRows(source.getSessionMaxRows()); }
复制代码


MySQL-JDBC Loadbalance 参数说明


明白了 MySQL-JDBC 的 Loadbalance 的相关机制,最重要的还是要对相关的参数有个详细的了解,并且设置有效的值,Loadbalance 相关一共有十几个参数,几个比较关键的如下表所示:




其他还有几个参数,一般用不到,也就不罗列出来了。


本文转载自公众号中间件小哥(ID:huawei_kevin)。


原文链接:


https://mp.weixin.qq.com/s/baxyONDEHTlPrSwszjo3Jw


2019-10-21 14:051304

评论

发布
暂无评论
发现更多内容

这可能是全网最晚的低代码技术总结

互联网工科生

低代码 低代码平台

快速实现一个企业级域名 SSL 证书有效期监控巡检系统

观测云

监控告警 智能巡检 SSL域名

一站式解决方案:体验亚马逊轻量服务器的顶级服务与灵活性

-亦世凡华、

瓴羊重磅发布数据服务枢纽“瓴羊港”,推动企业数据流通及价值增长

B Impact

Paste for Mac(剪切板历史管理工具)v4.1.2永久激活版

mac

苹果mac Windows软件 Paste 剪切板软件

搭建二维码系统,轻松实现固定资产的一物一码管理

草料二维码

文心一言 VS 讯飞星火 VS chatgpt (129)-- 算法导论11.1 4题

福大大架构师每日一题

福大大架构师每日一题

Amazon EC2 安全可调用的云虚拟主机服务器

追风少年

Amazon Aurora

最新intellij idea 2023 Mac破解版 附安装教程

影影绰绰一往直前

IntelliJ IDEA 2023下载 IntelliJ IDEA 2023破解 IntelliJ IDEA 2023最新 IntelliJ IDEA 2023中文

云网翼连智算未来| 重温天翼云全球行•亚太站精彩盛况

天翼云开发者社区

云计算

一种Mysql和Mongodb数据同步到Elasticsearch的实现办法和系统

天翼云开发者社区

MySQL 数据库

深入Vue.js与TypeScript的生命周期

K8sCat

vue.js 生命周期

sip中继的介绍

ctsxiyou

SIP

企业该如何选择数字化转型工具?

优秀

数字化转型 数字化工具

macOS苹果电脑终端SSH管理工具中文激活版Termius

iMac小白

Termius下载 Termius for Mac下载 Termius for Mac破解

sip中继是什么意思

ctsxiyou

SIP

Amazon EC2 Hpc7g 实例现已在更多区域推出

亚马逊云科技 (Amazon Web Services)

Amazon EC2

Amazon EC2 云服务器体验感爆了

归来

Amazon EC2 云服务器

Web项目常用的技术栈有哪些?

这我可不懂

软件开发 低代码 JNPF

人大金仓三大兼容:SQL Server迁移无忧

科技热闻

第26期 | GPTSecurity周报

云起无垠

软件测试/测试开发丨如何利用ChatGPT自动生成测试用例思维导图

测试人

软件测试

视频直播场景下对象存储的应用

天翼云开发者社区

对象存储

软件测试/测试开发丨Python安装指南(Windows版)

测试人

Python 软件测试

向量数据库的崛起与多元化场景创新

向量数据库

投资机构Janus Capital Group为Rola-IP品牌融资700万美元

Geek_ccdd7f

用了低代码工具,让我效率提升了80%

树上有只程序猿

软件开发 低代码开发平台 JNPF

Windows、Linux 和 Mac三个操作系统的对比

小魏写代码

私域流量搭建与运营,全是技巧攻略!

鲸品堂

运营 流量 企业号11月PK榜

罗拉ROLA住宅代理IP市场稳定增长,未来有哪些发展前景?

Geek_ccdd7f

大语言模型“战国时代”,未来将如何发展?

申屠鹏会

AI大语言模型

MySQL-JDBC Loadbalance深入解析_文化 & 方法_苗永辉_InfoQ精选文章