内容简介:层实现的读写分离,偏小众,但很有效。我们经常使用的MySQL驱动jar包,其实默认有非常棒的功能,那就是主从分离和HA。如果你只是需要一个主从分离、failover的功能,不要sharding。一个驱动就够了,不需要引入什么中间层。这个东西就是Replication协议。Mysql JDBC Connector在5.1.X版本之后增加了这些功能,以支持“multi-host”集群拓扑的访问范式。这个功能是在驱动层实现的,而既然是驱动层,那就不可避免有一些驱动层的问题(详见
官方驱动
层实现的读写分离,偏小众,但很有效。
JDBC驱动
我们经常使用的MySQL驱动jar包,其实默认有非常棒的功能,那就是主从分离和HA。如果你只是需要一个主从分离、failover的功能,不要sharding。一个驱动就够了,不需要引入什么中间层。
这个东西就是Replication协议。Mysql JDBC Connector在5.1.X版本之后增加了这些功能,以支持“multi-host”集群拓扑的访问范式。这个功能是在驱动层实现的,而既然是驱动层,那就不可避免有一些驱动层的问题(详见 《“分库分表" ?选型和流程要慎重,否则会失控》 。
我们平常的jdbc连接是这样
jdbc:mysql://127.0.0.1:3306/test?characterEncoding=UTF-8 复制代码
而经过协议改造后的jdbc连接,长得要长一些、大一些!
jdbc:mysql:replication://127.0.0.1:3306,127.0.0.1:3307,127.0.0.1:3308/test?useUnicode=true&characterEncoding=UTF-8&autoReconnect=false&loadBalanceStrategy=random 复制代码
当然,也可以有ipv6的写法,更加直观
jdbc:mysql://address=(type=master)(host=master1host),address=(type=master)(host=master2host),address=(type=slave)(host=slave1host)/db 复制代码
8.0的文档看这里: dev.mysql.com/doc/connect… 说明:
协议的第一个 连接
,表示主库 Master
后面的 一堆连接
,表示从库 Slave
,当然可以有多个 当你把 Master
的 连接
也放在后面的一堆里,那么它也拥有了“读库“的属性了 后面有一堆参数,来控制这 所有连接
,到底要如何相处
这样,所谓的主从分离功能,只要配置好这个连接串,就枯木逢春了。
代码层
首先你要改驱动类,再也不是Driver了,而是这个
com.mysql.jdbc.ReplicationDriver 复制代码
这种情况下 DataSource.getConnection() 获取的连接,实际上是ReplicationConnection,这个连接是虚拟的,和真实的数据库连接是个1对多的关系,所以记得给每一个MySQL都做上相应的机器授权。
那么如何来区别本次请求是读是写呢?靠的其实是 Connection
中的 readonly
属性,这个属性是通过请求 header
中的“readonly”传递的。所以如果请求中有写入操作,这整个的事务就一定是readonly=false的。
对于Spring来说,就可以使用 @Transactional
注解来控制这个属性了。一个事务不可能跨两个连接,所以是读是写,有最高层决定。
以下代码片段展示了你应该配置的一些元素,没错,就是注解。
public interface UserManager { public UserDO get(int id); public void insert(UserDO user); public void update(int id); } 复制代码
@Component public class UserManagerImpl implements UserManager{ @Autowired private UserDao userDao; ... @Override @Transactional(readOnly = false,propagation = Propagation.REQUIRED) public void insert(UserDO user) { this.userDao.insert(user); } } 复制代码
是不是很简单?等等,别高兴太早。
参数
不要觉得是官方驱动,就可以任性的用。这套jdbc驱动的参数还是非常丰富的,学习的代价也就高了些。在一些小流量下运行的很好,但在高并发环境下会频繁发生问题。这里只挑最重要的说下。
一个虚拟连接,对应着一个真正的主库连接和多个从库连接。对于主机的存活和重新上线,我们要考虑三种情况:
-
Master都死掉了
-
Slave都死掉了
-
Master、Slave全都死掉了
无论哪种情况,MySQL驱动都表现出一些奇怪的行为,默认参数是不好使的。
你可能以为驱动也就是管理一下几个连接而已,但情况比这复杂的多。首先给张图看下这个复杂的关系。
实例既然有下线、就有上线。上线以后要能够继续服务,此参数用来控制断线情况下自动重连而不抛出异常。这会破坏事务的完整性,但还是默认开启。
然而MySQL驱动提供了更加丰富的参数来控制这个过程,如果你的业务要求比较苛刻,这些参数可能要测个遍才会放心。 但大多数情况下,它运行的很好。
管理
仅有配置参数,此协议就算一个半成品而已。所幸,此驱动提供了JMX管理的方式,可以基于其做一些配置变更之类的功能。市面上并没有这种配置管理工具,可能还是因为它太小众了。
public abstract void addSlaveHost(String groupFilter, String host) throws SQLException; public abstract void removeSlaveHost(String groupFilter, String host) throws SQLException; public abstract void promoteSlaveToMaster(String groupFilter, String host) throws SQLException; public abstract void removeMasterHost(String groupFilter, String host) throws SQLException; public abstract String getMasterHostsList(String group); public abstract String getSlaveHostsList(String group); public abstract String getRegisteredConnectionGroups(); public abstract int getActiveMasterHostCount(String group); public abstract int getActiveSlaveHostCount(String group); public abstract int getSlavePromotionCount(String group); public abstract long getTotalLogicalConnectionCount(String group); public abstract long getActiveLogicalConnectionCount(String group); 复制代码
我们顺便提一下阿里的德鲁伊数据库连接池。如图,某些功能,只支持默认的单连接,对multi-host支持还是有限。
结尾
MySQL 5.1.x官方驱动出了这么个东西以后,其实宣告了很多小公司自研的某些小中间件的死亡。翻来服务,改写JDBC,不过就是为了管理个连接集合。
本文对象为专注基础设施研发的同学。有人看到的,不过是一堆参数而已;而真正去深入使用的人,会感到背脊通彻的寒冷。
当它小众时,你对它不屑一顾。然而当你一旦采用了某种方案,你却希望全世界都是关于它的描写。人生从来就没那么幸运,很多坑,还需要自己来踩。
以上所述就是小编给大家介绍的《”MySQL官方驱动“主从分离的神秘面纱(扫盲篇)》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
ANSI Common Lisp
Paul Graham / Prentice Hall / 1995-11-12 / USD 116.40
For use as a core text supplement in any course covering common LISP such as Artificial Intelligence or Concepts of Programming Languages. Teaching students new and more powerful ways of thinking abo......一起来看看 《ANSI Common Lisp》 这本书的介绍吧!