返回顶部
首页 > 资讯 > 数据库 > MySQL-JDBC Loadbalance深入解析
  • 229
分享到

MySQL-JDBC Loadbalance深入解析

摘要

背景说明 公司的整个电商系统搭建在华为云上,根据老总的估计,上线3个月之后日订单量会达到百万级别,保守估计3个月之后总订单个数预计会有5千万。Mysql单表达到千万级别,就会出现明显的性能问题。 根据如此规模的数据,当时考虑了2套解决方案:


	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相关一共有十几个参数,几个比较关键的如下表所示:

技术图片
技术图片

MySQL-JDBC Loadbalance深入解析

原文地址:Https://blog.51cto.com/15049785/2561499

您可能感兴趣的文档:

--结束END--

本文标题: MySQL-JDBC Loadbalance深入解析

本文链接: https://lsjlt.com/news/8013.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • MySQL-JDBC Loadbalance深入解析
    背景说明 公司的整个电商系统搭建在华为云上,根据老总的估计,上线3个月之后日订单量会达到百万级别,保守估计3个月之后总订单个数预计会有5千万。MySQL单表达到千万级别,就会出现明显的性能问题。 根据如此规模的数据,当时考虑了2套解决方案:...
    99+
    2014-12-19
    MySQL-JDBC Loadbalance深入解析 数据库入门 数据库基础教程 数据库 mysql
  • 关于JDBC与MySQL临时表空间的深入解析
    背景 临时表空间用来管理数据库排序操作以及用于存储临时表、中间排序结果等临时对象,相信大家在开发中经常会遇到相关的需求,下面本文将给大家详细JDBC与MySQL临时表空间的相关内容,分享出来供大家参考学习...
    99+
    2024-04-02
  • 一文深入解析JDBC超时机制
    目录前言JDBC执行SQL的原理证明kill命令详解总结资料前言 上周在线上出现出现报警,ID号码一直无法获取,但是只有这一台机器报警,所以第一时间先在服务治理平台上禁用掉这台机器...
    99+
    2024-04-02
  • 深入解析MySQL 事务
    目录事务的四大特性 ( ACID )脏读不可重复读幻读MySQL的隔离级别事务指逻辑上的一组操作,组成这组操作的各个单元,要么全部成功,要么全部失败。 事务的四大特性 ( ACID ...
    99+
    2024-04-02
  • MySQL 8.0 redo log的深入解析
    前言 最开始了解mysql实现的时候,总听到redo log, WAL(write-ahead logging),undo log这些关键词,了解到redo log主要是用于实现事务的持久化的。为了进一步了解red...
    99+
    2022-05-24
    MySQL 8.0 redo log MySQL redo log解析
  • 深入浅析MySQL Explain
    目录一、id二、select_type三、table四、type五、possible_keys六、Key七、key_len八、ref九、rows十、Extra在日常工作中,我们会有时会开慢查询去记录一些执行时间...
    99+
    2022-07-08
    MySQL Explain MySQL Explain详解
  • 深入浅析MySQL Explain
    目录一、id二、select_type三、table四、type五、possible_keys六、Key七、key_len八、ref九、rows十、Extra在日常工作中,...
    99+
    2024-04-02
  • 深入解析MySQL MVCC 原理与实现
    深入解析MySQL MVCC 原理与实现MySQL是目前最流行的关系型数据库管理系统之一,它提供了多版本并发控制(Multiversion Concurrency Control,MVCC)机制来支持高效并发处理。MVCC是一种在数据库中处...
    99+
    2023-10-22
    原理 MySQL mvcc
  • 深入解析MySQL索引数据结构
    目录概述索引数据结构 二叉树 红黑树 B-Tree B+Tree Hash 索引 InnoDB 索引实现(聚集) 索引文件和数据文件是分离的(非聚集) 聚集索引和非聚集索引 联合/复...
    99+
    2024-04-02
  • UNDO Segment深入解析
    Undo Segment深入解析  在undo自动管理时,设置了undo_retention以后,undo块就存在四种状态。Active:表示正在使用该undo的事务还没有提交或回滚。Inacti...
    99+
    2024-04-02
  • 深入解析golang bufio
    目录bufio 包介绍 golang bufio使用bufio进行写缓存中满数据缓存中仍有空间待写入的数据大于缓存的大小缓存重用获取缓存的可用空间数使用bufio进行读Pe...
    99+
    2024-04-02
  • 深入浅析Android JSON解析
    JSON语法 首先看JSON的语法和结构,这样我们才知道怎么去解析它。JSON语法时JavaScript对象表示语法的子集。 JSON的值可以是: 数字(整数或者浮点数) 字符...
    99+
    2022-06-06
    json解析 android json解析 JSON Android
  • 如何深入解析MySQL分区Partition功能
    这篇文章将为大家详细讲解有关如何深入解析MySQL分区Partition功能,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。 自5...
    99+
    2024-04-02
  • 【MySql系列】深入解析数据库索引
    写在前面  MySQL索引是数据库中一个关键的概念,它可以极大地提高查询性能,加快数据检索速度。但是,要充分发挥索引的作用,需要深入理解它们的工作原理和使用方式。 在本文中,我们将深入解析MySQL索引,探讨它们的重要性、类型、创建...
    99+
    2023-10-18
    数据库 mysql mysql索引 原力计划
  • 深入解析MySQL中的各种锁机制
    MySQL 各种锁详解一、引言在并发访问中,数据库需要使用锁来保护数据的一致性和完整性。MySQL 提供了多种类型的锁,包括共享锁、排他锁、意向共享锁、意向排他锁等。本文将使用具体的代码示例介绍并解析这些锁的使用方式和特点。二、共享锁(Sh...
    99+
    2023-12-21
    MySQL - 事务 - 行锁 - 表锁
  • 深入解析java.lang.ClassNotFoundException异常
    1. 引言 在Java开发中,我们经常会遇到各种异常。其中,java.lang.ClassNotFoundException异常是一种常见的异常。本文将深入解析这个异常的定义、作用、产生原因以及常见场景。 1.1 介绍ClassNotFou...
    99+
    2023-08-30
    java 开发语言
  • 深入解析java.lang.IllegalStateException异常
    异常概述 什么是异常 异常是程序在执行过程中遇到的错误或异常情况。在Java中,异常是指在程序运行期间发生的错误,它可以打破程序的正常流程,并且可能导致程序终止。 异常的分类 异常分为两种类型:受检异...
    99+
    2023-08-31
    java python 大数据
  • GoComparableType原理深入解析
    目录介绍内部实现现实中的陷阱与应用errors.Is(*Type)(nil) ≠ nilContext Value Key指针类型Struct 类型介绍 在 Go reflec...
    99+
    2023-01-06
    Go Comparable Type原理 Go Comparable
  • 深入解析:从源码窥探MySQL优化器
    作者 | 汤爱中,云和恩墨SQM开发者,Oracle/MySQL/DB2的SQL解析引擎、SQL审核与智能优化引擎的重要贡献者,产品广泛应用于金融、电信等行业客户中。摘要优化器是逻辑SQL到物理存储的解释器...
    99+
    2024-04-02
  • MySQL索引设计原则深入分析讲解
    哪些情况适合创建索引? 字段的数值有唯一性的限制 索引本身可以起到约束的作用,比如唯一索引,主键索引都是可以起到唯一性约束的,因此在我们的数据表中如果某个字段是唯一性的,就可以直接创...
    99+
    2023-01-02
    MySQL索引设计原则 MySQL索引
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作