【AICon】探索RAG 技术在实际应用中遇到的挑战及应对策略!AICon精华内容已上线73%>>> 了解详情
写点什么

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:051275

评论

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

sketch文件导出没有背景色怎么办? sketch背景色消失的解决办法

Rose

Sketch下载 sketch无背景 矢量图设计 sketch mac破解版

photoshop 2022新功能介绍 含ps2022破解版下载资源

Rose

ps PS2022下载 Photoshop 2022下载 Photoshop 2024破解版

BOE(京东方)与JDG京东电竞俱乐部达成全面品牌战略合作 赋能多款高端电竞新品开启2024电竞产业“开门红”

科技热闻

用Python实现高效数据记录!Web自动化技术助你告别重复劳动!

测吧(北京)科技有限公司

测试

和鲸CEO范向伟入选2022年上海市东方英才计划创业项目领军创业人才

ModelWhale

人工智能 创业 AI 东方英才 前沿产业

顺丰科技智慧供应链助力自动化立体仓库建设

新消费日报

ChatGPT:故障频发背后的反思,重新理解稳定性

焦振清

稳定性 稳定性治理 AZ 逃生 蓝军

华为阅读合作伙伴年度会议圆满举行,将持续共建更智慧、更丰富数字阅读平台

最新动态

CQ 社区版 2.8.0 | 支持TiDB、StarRocks,新增列过滤算法、导出模式设置等

BinTools图尔兹

数据库 数据库管理 数据脱敏 数据变更

【wayn商城】本地开发指南

越长大越悲伤

Java 开源 前端 后端 wayn商城

免费的快递预约上门取件API接口【快递鸟】

快递鸟

快递物流

点燃你的Python技能:剖析闭包与装饰器的魔力

测吧(北京)科技有限公司

测试

云上业务一键性能调优,应用程序性能诊断工具 Btune 上线

Baidu AICLOUD

性能优化 运维监控

共话 AI for Science | 北京大学王超名:BrainPy,迈向数字化大脑的计算基础设施

ModelWhale

人工智能 AI 脑科学 AI4S 类脑智能

怎样解决注塑行业的难点与现状?

万界星空科技

mes 万界星空科技 万界星空科技mes 注塑MES 注塑行业

基于开源IM即时通讯框架MobileIMSDK:RainbowChat v11.0版已发布

JackJiang

网络编程 即时通讯 IM

百万级监控指标的秒级采集与处理

鲸品堂

监控 解决方案

试用强大的百度智能云【AI原生应用工作台】实现《毛泽东传记问答》实操记录

livingbody

AI BAIDU 知识库 人工智能「 知识库问答

测试管理 | 测试开发高薪私教线下班手把手带你提升职业技能

测吧(北京)科技有限公司

测试

聚焦AI4S,产学研专家齐聚,探讨AI工具在多领域应用的现状与趋势

ModelWhale

​比特币大跌的 2 个原因

TechubNews

从零开始:编写个性化的 Spring Boot 启动 Banner

Liam

Java 程序员 DevOps Spring Boot 后端

高效灌溉 - 真正意义的降本增效

zhumingwu

Python多任务协程:编写高性能应用的秘密武器!

测吧(北京)科技有限公司

测试

青否互动式数字人高智商、有灵魂的大脑!

青否数字人

数字人

深入了解Redis数据结构

EquatorCoco

redis 数据结构 前端

React和Vue的有何不同?

伤感汤姆布利柏

如何实现一个百万亿规模的时序数据库,百度智能云 BTS 架构解析和实践分享

Baidu AICLOUD

时序数据库

移动开发平台真的能达到降本增效吗?

Geek_2305a8

想拥有一个属于自己的网站吗?

zhumingwu

【新手快速入门】在线快速搭建AI原生应用

AI大咚咚

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