一、Connector与Failover协议
Mysql Connector/J支持failover协议:即Client链接失效时,将会尝试与其他host建立链接,这个过程对上层应用是透明的。Failover协议是“Multi-Host”链接模式中最基础的协议,“load balancing”、“replication”、“farbic”协议都基于Failover协议。其URL格式如下:
jdbc:mysql://[primary-host]:[port],[secondary-host]:[port],.../[database]?[property=<value>]&[property=<value>]
Host列表中有两种hosts:primary(master)和secondaries(slaves),priamry需要位于hosts列表的第一个;当创建一个新的connection时,driver会首先尝试与primary链接,如果primary链接异常,将会依次与secondaries建立链接直到成功为止;即使与primary的链接失效,但是driver并不会丢失primary的特殊状态:比如它的访问模式、优先级等。
Failover协议支持如下属性:
1)failOverReadOnly
2)secondsBeforeRetryMaster
3)queriesBeforeRetryMaster
4)retriesAllDown:当所有的hosts都无法连接时重试的最大次数(依次循环重试),默认为120。重试次数达到阈值仍然无法获取有效链接,将会抛出SQLException。
5)autoReconnect
6)autoReconnectForPools
“failOverReadOnly”用于控制connection中“read_only”参数,即当primary链接失效时,failover到secondary时链接的默认访问模式,此值默认为“true”,即与secondary的链接访问模式为“只读”;通常情况下,primary的链接访问模式为“read/write”,即read_only为false。Connector J在failover时可以修改read_only的值,当然application在获取链接后也可以调整此值。无论何时,failover到primary的链接总是“read/write”模式;当Client与primary的链接失效时(可能primary节点并没有失效),如果failOverReadOnly为false,表示与secondary的连接上允许发生“write”操作,这极有可能是危险的,因为slaves上如果被Client写入数据将导致replicaiton集群中的数据不一致,除非slaves节点上已经设定了全局“read_only=true”。
在failover发生后,Driver会定期检测primary的链接状况,如果发现primary的链接恢复正常,那么客户端链接也将会“Fallback”(回落)到primary上,即此后的read/write将在primary链接上发生(与secondary的链接将会保持空闲,或者断开)。“secondsBeforeRetryMaster”表示driver每隔多少秒将重试master的链接,“quriesBeforeRetryMaster”表示执行多少次queries后重试master的链接,如果重试成功,则将会“Fallback”到primary上;可以将上述两个属性设置为“0”来关闭自动Fallback。
当primary的链接失效后,触发failover,此时driver将依次与hosts列表中的secondary建立链接,直到与某个Secondary链接成功,否则将所有的secondaries都尝试完毕,然后继续从头开始,直到与其中一个secondary链接成功。如果所有的hosts都无法链接,driver最多重试“retriesAllDown”次(默认为120)。
“autoReconnect”、“autoReconnectForPools”这两个参数用于控制“重连”特性,即当一个session(或者事务)操作过程中,如果链接异常,driver不会抛出Exception而是尝试重新链接并继续执行;如果你的操作是非事务性的(Query或者变更MyISAM表),reconnect通常不会带来问题;但是如果是一个事务操作,在事务中的多个操作过程中发生重连,有可能会对session状态造成破坏,从而导致数据不一致性问题,即使开启“autocommit=false”时仍然不能避免问题,事实上重连之后并不会rollback原来中断的事务,而是继续进行,参见【autoReconnect】。此参数选项将会在未来的版本中被移除,也有可能不同版本的Connector J中实现会有不同,建议开发者禁用此特性。
Failover协议,它解决了:当master失效后,Driver能够透明的与其他secondary建立链接,当master恢复后,能够自动的Fallback到primary。对于application而言,可以利用“replication”架构的优势,以提高可用性;MySQL实例的故障或者恢复,不需要调整application代码。
参见源码:FailoverConnectionProxy,它为代理类,即Connection上的所有操作方法均有此proxy代理。
二、Connector与Load Balancing(LB)
Failover协议并没有提供“load balancing”特性,即读(写)操作总是只发生在一个host上。对于“replication”、“多Master”架构,我们通常希望“负载均衡”、“读写分离”等高级特性,这就是Load Balancing协议所能解决的。Load Balancing可以将read/write负载,分布在多个MySQL实例上,这些MySQL实例通常为Cluster架构或者Replication架构,本文主要讲解“Replication”架构相关的知识。LB协议基于“Failover协议”,即具备Failover特性,其URL格式:
jdbc:mysql:loadbalance://[host]:[port],[host]:[port],...[/database]?[property=<value>]&[property=<value>]
LB协议支持2个配置选项:
1)loadBalanceConnectionGroup:将来自不同资源(hosts)的链接进行分组,通常每个LB协议都需要一个group名字,所有的LB链接都共享一个group名称,特别是当JVM进程上有多个LB Datasource时。
2)loadBalanceEnableJMX:当定义group名称后,可以将管理链接的方式暴露给JMX。此后可以通过JMXBean(LoadBalanceConnectionGroupManagerMBean)相关接口来管理和操作:比如运行时增减hosts列表等。
3)loadBalanceStrategy:负载均衡的策略,默认值为“random”;其支持简写值为“random”、“bestResponseTime”(最小响应时间优先);对于其他负载均衡策略,需要指定类的全名。请参见BalanceStrategry的实现类。
4)loadBalanceBlacklistTimeout:为loadBalanceStrategy服务,如果某个节点请求时返回SQLException,那么此host将会被添加到黑名单中,在此后的timeout时间内下一次选择时将不会再被选中。默认值为0,表示“立即过期”,即每次重新选择连接时都将参与选择(本次选择时加入黑名单后,将不会在本次选择时考虑)。其中内部机制比较简单,在获取新连接时,首先获取并检查黑名单列表,此时会检测timeout时间是否过期,如果过期将从黑名单列表中移除,并允许此host参与本次选择。(参见LoadBalanceConnectionProxy.getGlobalBlacklist())
LB协议允许在运行时增减hosts,这对二次开发的人来说非常有用,本文将不再赘言。
driver创建的LoadBalancedConnection是一个逻辑链接,其内部持有一个物理链接列表,即与每个host建立一个Connection。1)当autocommit为false时,在事务的边界方法执行后,比如commit、rollback,将会触发BalanceStrategy从host列表中重新选择新的链接。2)当链接上发生Exception时,比如socket异常,将会导致重新选择链接。3)当autocommit为true时,当链接上执行“loadBalanceAutoCommitStatementThreshold”个statements后(Queries或者updates等),将会导致重新选择链接,默认为0表示“粘性链接,不重新选择链接”。(这是负载均衡的一种补偿措施)
选择链接的方式参见LoadBalancedConnectionProxy.pickConnection()。(以及其invokeMore()方法,注意本文中提到的*ConnectionProxy类均为代理类,JAVA动态代理,代理对应的*Connection方法)
参见源码:LoadBalancedConnectionProxy,BalanceStrategy,LoadBalancedConnection
Driver driver = new NonRegisteringDriver(); Properties properties = new Properties(); properties.put("user",USER); properties.put("password",PASSWORD); properties.put("loadBalanceAutoCommitStatementThreshold","2"); Connection connection = driver.connect("jdbc:mysql:loadbalance://127.0.0.1:3306,127.0.0.1:4306,127.0.0.1:5306/mydb", properties); ResultSet resultSet = connection.createStatement().executeQuery("SELECT * FROM test where id = 1"); while (resultSet.next()) { Date created = resultSet.getDate(2); System.out.println(DateFormatUtils.format(created, "yyyy-MM-dd HH:mm:ss")); } resultSet.close(); connection.close();//将导致LoadBalancedConnection中所有的连接关闭
LoadBalancedConnectionProxy为代理类,Connection上的所有方法操作均其代理,因此它可以在执行方法时选择“内部的物理链接”执行,达到LB的效果。
三、Connector与Replication
Replication是MySQL最常见、最有效的架构模式之一,Replication协议基于Failover与LB,只适用与replicaiton架构,主要用于解决replication架构下“读写分流”、“负载均衡”等问题。其URL格式为:
jdbc:mysql:replication://[master-host]:[port],[slave-host]:[port],.../database?[property=<value>]
在5.127版本之后,relplication协议也支持了多master模式,此时协议样例为:
jdbc:mysql:replication://address=(type=master)(host=master1host),address=(type=master)(host=master2host),address=(type=slave)(host=slave1host)/database
Replication协议主要参数:
1、“allowMasterDownConnections=true”属性表示当master失效时可以继续创建其Connections对象,但是Connection的访问模式为“read_only=true”,当master有效后会调用Connection.setReadOnly(false)方法修改其访问模式,在此之前如果通过Connection提交writes操作将会抛出异常,此属性默认值为false。“allowSlavesDownConnections=true”表示当所有的slaves都失效时是否也能创建相应的Connections对象,访问模式也是“read_only=true”,此链接有效之前如果通过Connection发送read操作将会抛出异常,此属性默认值为false。“readFromMasterNoSlaves”表示如果所有的slaves都不可用,read操作将在master连接上发生,此属性默认值为false。
2、“readFromMasterWhenNoSlaves”表示当所有的slaves都失效(异常)时,是否允许将read请求转发给master。默认为false,建议设置为true。
在replication模式下,默认slaves的负载均衡的策略与LoadBalance协议保持一致,而且由Connection.getReadOnly()值决定;如果read_only为true,Replication Connection将使用“随机”模式选择一个slave链接,如果所有的slaves都失效,此时将使用master链接(由readFromMasterNoSlaves参数控制)。如果你需要提交write请求或者read实时数据,那么需要将read_only=false,那么read/write操作将在master链接上发生。master链接上除了可以接受read_only外,还可以指定autocommit和事务隔离级别。
还有一个比较重要的参数“replicationConnectionGroup”,我们为一组master-slaves指定唯一的group名称,此后即可通过“ReplicationConnectionGroupManager”来跟踪链接以及动态管理hosts列表,即允许开发者在运行时动态调整hosts拓扑结构。(比如addSlaveHost,promoteSlaveToMaster等等)。
ReplicationDrvier创建的Connection类型为ReplicationConnection,ReplicationConnection也由ReplicationConnectionProxy代理执行;每个ReplicationConnection对应一个proxy实例,每个proxy内部都持有一个masterConnection和类型为LoadBalancedConnection的slavesConnection,因此slaves链接具备LB特性。如果read_only为false,那么在执行操作方法时,proxy将选择masterConnection;否则将从slavesConnections中选择一个。每个ReplicationConnection均会与所有的host建立一个物理链接,这一点需要清楚,这会导致每个MySQL实例(master、slave节点)都持有相同的连接数。
参见源码:ReplicationConnection,ReplicationDriver,ReplicationConnectionProxy。
ReplicationDriver driver = new ReplicationDriver(); Properties properties = new Properties(); properties.put("user",USER); properties.put("password",PASSWORD); Connection connection = driver.connect("jdbc:mysql:replication://127.0.0.1:3306,127.0.0.1:4306,127.0.0.1:5306/mydb", properties); connection.setAutoCommit(true); connection.setReadOnly(true); ResultSet resultSet = connection.createStatement().executeQuery("SELECT * FROM test where id = 1"); while (resultSet.next()) { Date created = resultSet.getDate(2); System.out.println(DateFormatUtils.format(created,"yyyy-MM-dd HH:mm:ss")); } resultSet.close(); connection.close();
四、Connector J问题小结
1、选择合适的Driver:对于Failover和LB协议,可以选用NonRegisterDriver;对于replication协议,我们需要使用ReplicationDriver。对于单点host,普通的Driver类即可。
2、为了便于跟踪replication模式下,LB协议是否生效或者query在哪个节点执行,我们可以开启“general_log”功能:
>SET GLOBAL general_log=1; >select @@global.general_log;
3、autoReconnect属性建议禁用,因为在事务操作中,如果链接重连并不会导致事务回滚而是继续执行,这会带来事务完整性的问题,导致数据不一致。具体原理参见【autoReconnect】
参考文档:
1、https://dev.mysql.com/doc/connector-j/en/connector-j-usagenotes-troubleshooting.html
2、https://dev.mysql.com/doc/connector-j/en/connector-j-multi-host-connections.html
3、https://dev.mysql.com/doc/connector-j/en/connector-j-reference-configuration-properties.html
相关推荐
针对这一情况,提出在现有硬件的基础上利用JDBC规范与MySQL Replication实现数据库集群从而解决数据访问瓶颈。其主要方法是在进行JDBC连接之前实现负载均衡,所有SQL请求由负载均衡器进行统一调度。在数据库端利用...
springboot + mysql + jdbc的简单示例,运行Application就可以运行,访问localhost:8080/test/hi可以查出用户列表
PostgreSQL Replication
Mysql Replication about GTID Concepts and sets&。
Windchill Remote Replication Servers
DB2 Q replication配置方法。经本人测试通过。 DB2 Q replication配置方法。经本人测试通过。 DB2 Q replication配置方法。经本人测试通过。 DB2 Q replication配置方法。经本人测试通过。
antagonize influenza virus replication.antagonize influenza virus replication.antagonize influenza virus replication.antagonize influenza virus replication.antagonize influenza virus replication....
Pro SQL Server 2008 Replication Pro SQL Server 2008 Replication Pro SQL Server 2008 Replication
mysql replication搭建
HANA system replication
Veeam® Backup & Replication™ 是一款强大、易于使用和价格经济的备份与可用性解决方案, 支持快速、灵活且可靠地恢复虚拟化应用程序和数据,将虚拟机 (VM) 备份和复制功能整合在单个软件解决方案中。 Veeam ...
python-mysql-replication, 在PyMYSQL之上,MySQL复制协议构建的纯 python 实现 python-mysql-replication MySQL复制协议在PyMYSQL之上的纯 python 实现。 这允许你接收诸如插入。更新。delete 和它们的数据和原始...
一本关于Oracle Advanced Replication的书
大多数人都知道Streaming Replication已经成为PostgreSQL的一部分,并且通常用于高可用性和读写分离,流复制是基于WAL日志的物理复制,适用于整个数据库实例的复制,并且备库是只读的。 Logical Replication属于...
SAP LT Replication Server Overview
postgresql replication源码解析。
stream replication 双向复制安装配置文档
Part III: Web Replication Chapter 14. Basic Mechanisms for Request Distribution Section 14.1. Content-Blind Request Distribution with Full Replication Section 14.2. Content-Blind Request ...