Shardingsphere-JDBC初体验

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即可。

Shardingsphere-JDBC初体验_第1张图片

如果构建过程没有报错,并且构建完成之后,控制台出现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
                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表中,成功插入了一条数据。可见分库分表确实起了作用。

Shardingsphere-JDBC初体验_第2张图片

五.分库分表逻辑分析

通过代码的配置,大概能推测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/

你可能感兴趣的:(技术,数据库,中间件)