一、背景介绍
sharding-jdbc本来是当当网内部解决分库分表的问题的一个内部组件,后来慢慢开源了然后现在捐给了apache,成为了apache的一个子项目,但是当当自己还在维护自己的。除了shrading-jdbc,当当还开源了elastic-job、基于dubbo的dubbox。
在apache中,sharding-jdbc改名叫做shardingsphere,其包含了sharding-jdbc和sharding-proxy,其中sharding-jdbc是应用在客户端的,而sharding-proxy应用在代理端的。
一般来说,操作数据库可以从以下的顺序进行操作:
其中dao,orm,jdbc都是代码层的操作。
我们使用的sharding-jdbc是jdbc层的,其实现了jdbc协议,而mycat和sharding-proxy是proxy层的。mycat可以当做一个mysql数据库来使用,而且其也实现了jdbc协议。
二、sharding-jdbc和mycat在项目中的使用流程
1、sharding-jdbc的使用流程
1.1、导入sharding-jdbc的jar包;
1.1、在yml中配置数据源,配置分片策略(包括分库的策略和分表的策略),sharding-jdbc官网提供了一些分片策略和分片算法,也可以自定义分片算法,分片算法可用于分库也可用于分表;
2、mycat的使用流程
mycat需要在其配置文件中配置分片策略和分片算法,如果自己想自定义也可以,其主要的配置文件是server.xml,schema.xml,rule.xml和具体的分片配置文件。
2.1、在server.xml文件中主要配置系统相关的信息,我们常用的是配置访问mycat这个mysql服务的用户名和密码;
2.2、在schema.xml中配置逻辑库、表、分片规则、分片节点和数据源;
定义了逻辑表,以及逻辑表分布的节点和分片规则:
数据节点与物理数据库的对应关系:
配置物理主机的信息,readhost 是从属于 writehost 的:
2.3、在rule.xml中定义分片规则和算法,分片规则对应相应的算法,算法可能对应具体的分片配置文件;
2.3、在具体的文件中配置分片,例如上面的rang-long-cust.txt,对应的就是一个txt文档,内容如下;
三、动态数据源
说到分库分表,就要考虑动态数据源,毕竟分为不同的库,要根据不同的需求切分不同的库,动态数据源我们可以从上面说的五个角度来具体实现。
dao:可用spring自带的abstractroutingdatasource动态数据源,自定义一个注解,然后再定义一个切面切注解,根据注解动态切换数据源;
orm:例如mybatis的插件可以实现动态数据源;
jdbc:可以使用sharding-jdbc来实现,在其yml文件中配置动态数据源;
proxy:可以使用mycat来实现,在schema.xml文件中配置动态数据源;
server:有的数据库自带能动态切换数据源,这个不常见。
四、分片的策略
1、mycat的分片策略:可以在rule.xml中找到mycat本身提供的分片规则和分片算法,也可以自定义算法,然后在rule.xml中命名然后指向相应的实现类即可;
2、sharding-jdbc有五种分片策略可供使用,但是也可以自定义分片规则,继承shardingstrategy然后实现自定义的分片策略即可。五种分片策略分别为:
2.1、行表达式分片策略:单个分片键,提供对=和in操作的支持,行表达式配置的比较简单。
2.2、标准分片策略:单个分片键,既可以使用精确分片算法又可以使用范围分片算法
2.3、复合分片策略:多个分片键,使用的是复合分片算法;
2.4、hint分片策略:类似于mycat的注解,使用的是hint分片算法;
2.5、不分片策略:看名字就知道,不说了。
五、分布式事务和全局id
1、sharding-jdbc中
1.1、分布式事务
这里只介绍一种简单的,xa两阶段提交,有兴趣的可以去harding-jdbc官网看具体的其他分布式事务的解决方案。
导入一下xa的jar包,xa默认是使用atomikos实现的。
在 service 类上加上注解即可解决分布式事务,但是并发性差:
1.2、全局id
默认使用雪花算法,也可以自定义一个算法,然后配置文件中配置即可。
2、mycat中
2.1、全局id
mycat提供了四种方式,文件方式,数据库方式,本地时间戳方式,zk方式,其原理都是在四个地方都存相应的id数据,每次从这几个地方取。
六、sharding-jdbc和jdbc四大核心的关系
1、sharding-jdbc和jdbc四大核心
jdbc的四大核心:datasource,connection,statement(preparestatement),resultset,而sharding-jdbc的四大核心也是shardingdatasource,shardingconnection,shardingstatement(shardingpreparestatement),shardingresultset,其实就是对jdbc的四大核心进行进一步封装而已。
2、为什么springboot项目中用到的是sharding-jdbc的四大核心而不是jdbc本身的呢?
因为使用了sharding-jdbc的starter,容器将其四大核心注入到了容器中,当需要使用的时候会自动注入这个四个核心。当使用datasource时选择了sharding-jdbc的,然后当使用connection创建连接时sharding-jdbc会动态代理jdbc的connection,因此 是用是sharding-jdbc。然后创建出来的statement或者preparestatement、resultset都是sharding-jdbc的。
例如整合mybatis以后的项目用sharding-jdbc,看过源码的都知道查询最后都走到了simpleexecutor的doquery()方法,想看这个流程的同学可以自己在这个地方打断点看看。
七、sharding-jdbc和mycat的区别以及选择
1、sharding-jdbc和mycat的区别
1.1、工作层次:sharding-jdbc实现了jdbc协议,工作在jdbc层;mycat可以当做一个mysql数据库使用,其实就是在proxy层的。
1.2、运行方式:sharding-jdbc只需要在工程中导入一个sharding-jdbc的jar包,然后在配置文件中配置相应的数据源和分片策略即可;mycat则是需要单独提供一个端口为8066的服务,然后在mycat的配置文件中配置相关的数据源和分片策略。
1.3、开发方式:sharding-jdbc只需要在配置文件中进行配置即可使用;mycat需要在其配置文件中修改数据源等一系列参数。
1.4、运维成本:sharding-jdbc的运维成本低,java开发人员的维护成本高;mycat运维成本高,得配置mycat的一系列参数以及高可用负载均衡的配置,需要一定的运维实力。
1.5、支持的语言:sharding-jdbc只支持java语言;mycat支持实现了jdbc规范的语言。
2、如何选择?
如果项目比较简单,需要使用的分片策略和算法不复杂,那么可以用sharding-jdbc;如果项目比较复杂,分片规则比较复杂,而且具有一定的运维能力,那么选择mycat。