Apache ShardingSphere(Incubator) 是一套开源的分布式数据库中间件解决方案组成的生态圈,它由Sharding-JDBC、Sharding-Proxy和Sharding-Sidecar(规划中)这3款相互独立,却又能够混合部署配合使用的产品组成。它们均提供标准化的数据分片、分布式事务和数据库治理功能,可适用于如Java同构、异构语言、容器、云原生等各种多样化的应用场景。[注1]
本文介绍如何使用Sharding-JDBC实现分库分表。基于的版本是4.0.0.M1-SNAPSHOT。
一.构建Shardingsphere
1.从官网下载Shardingsphere源代码,下载地址https://github.com/apache/incubator-shardingsphere
2.项目导入Intellij IDEA,使用Maven的install命令构建项目。可以直接在idea右边栏的Maven区找到sharding-sphere,点击install即可。
如果构建过程没有报错,并且构建完成之后,控制台出现BUILD SUCCESS,则说明构建成功,在你本地的Maven仓库中就会有jar包可以引用。
二.新建数据库和表
在mysql中新建两个数据库database1和database2(也可以叫别的名字),每个数据库建两张表t_order_0和t_order_1。建表语句如下:
create table t_order_0
(
id int auto_increment
primary key,
user_id int null,
order_id int null
);
create table t_order_1
(
id int auto_increment
primary key,
user_id int null,
order_id int null
);
三.搭建demo项目
1.新建一个maven项目,名为shardingsphere-demo,删除src文件夹,新建一个模块shardingsphere-jdbc-demo;
2.在根pom中对依赖进行管理,输入如下内容:
4.0.0.M1-SNAPSHOT 8.0.15 2.5.0 org.apache.shardingsphere sharding-jdbc-core ${shardingsphere.version} org.apache.commons commons-dbcp2 ${dbcp2.version} mysql mysql-connector-java ${mysql-connector-java.version}
3.在shardingsphere-jdbc-demo的pom文件中引入依赖和maven编译插件:
org.apache.maven.plugins maven-compiler-plugin 7
org.apache.shardingsphere sharding-jdbc-core org.apache.commons commons-dbcp2 mysql mysql-connector-java
4.开发代码
新建一个Demo类,添加如下代码:
public class Demo {
public static void main(String[] args) throws SQLException {
Map dataSourceMap = new HashMap<>();
BasicDataSource dataSource1 = new BasicDataSource();
dataSource1.setDriverClassName("com.mysql.jdbc.Driver");
dataSource1.setUrl("jdbc:mysql://localhost:3306/database0");
dataSource1.setUsername("root");
dataSource1.setPassword("mysql123!");
dataSourceMap.put("database0", dataSource1);
BasicDataSource dataSource2 = new BasicDataSource();
dataSource2.setDriverClassName("com.mysql.jdbc.Driver");
dataSource2.setUrl("jdbc:mysql://localhost:3306/database1");
dataSource2.setUsername("root");
dataSource2.setPassword("mysql123!");
dataSourceMap.put("database1", dataSource2);
TableRuleConfiguration tableRuleConfiguration = new TableRuleConfiguration("t_order");
tableRuleConfiguration.setDatabaseShardingStrategyConfig(new InlineShardingStrategyConfiguration("user_id",
"database${user_id % 2}"));
tableRuleConfiguration.setTableShardingStrategyConfig(new InlineShardingStrategyConfiguration("order_id",
"t_order_${order_id % 2}"));
ShardingRuleConfiguration shardingRuleConfiguration = new ShardingRuleConfiguration();
shardingRuleConfiguration.getTableRuleConfigs().add(tableRuleConfiguration);
DataSource dataSource = ShardingDataSourceFactory.createDataSource(dataSourceMap, shardingRuleConfiguration,
new Properties());
String sql = "insert into t_order (user_id, order_id) values (?, ?)";
Connection connection = dataSource.getConnection();
PreparedStatement preparedStatement = connection.prepareStatement(sql);
preparedStatement.setInt(1, 2);
preparedStatement.setInt(2, 2);
preparedStatement.execute();
}
}
简单解释一下代码逻辑:
(1)构建一个Map
(2)每个参与分库的数据库需要各自建立一个数据源,并且要将它作为value放入map中,并且key必须正确,所谓的正确就是分库分表组件在根据分库键计算出库名之后,这个库名必须能在map中找到;
(3)构建分表规则TableRuleConfiguration,这里设置了分库的规则,也就是数据库的前缀是database,而后缀是根据user_id模2得到的;也设置了分表的规则,具体含义与分表规则类似,请自行参考。
(4)构建ShardingRuleConfiguration对象,这个类是一个数据分片的总的配置类,通过代码可知,这个类有一个集合,专门用于存放我们上面构建的分库分表的规则,而这里就是要把上面的分库分表规则添加到这个规则集合中;
(5)通过Shardingsphere提供的工厂类获取数据源,需要我们上面的数据源map,数据分片配置类作为参数,以及一个属性配置类作为参数,当然本Demo中的属性配置类里面没有任何属性,在这里实际不起作用。
(6)按照JDBC的规则执行一条insert语句。
四.执行结果
执行结果是,在database0数据库的t_order_0表中,成功插入了一条数据。可见分库分表确实起了作用。
五.分库分表逻辑分析
通过代码的配置,大概能推测sharding-jdbc分库分表的逻辑。
1.根据map中的数据源分别和数据库建立连接,如果配置有问题则失败;
2.执行sql时,会根据配置的规则,用分库键去计算出命中的数据库名,用数据库名去map中取数据源,如果取不到则失败;
3.根据配置的分表规则,用分表键去计算出命中的数据表名;
4.替换sql中的库和表为计算出的实际的库和表,并尝试将数据插入其中。
六.总结
通过本文,我们发现shadingsphere-jdbc使用起来还是比较方便的,配置不算太复杂(一些高级的配置暂时还用不到)。它是一种客户端数据分片的技术,优点是不需要搭建额外的分库分表代理服务器,配置也比较简单。
后续还会继续尝试Shardingsphere-proxy,并对它的优缺点与Shardingsphere-jdbc进行比较分析。
附:
本项目源码地址:
https://github.com/tswstarplanet/shardingsphere-demo
注释:
1.https://shardingsphere.apache.org/