SpringBoot整合Sharding-Jdbc实现分库分表和分布式全局id

SpringBoot整合Sharding-Jdbc

Sharding-Jdbc

sharding-jdbc是客户端代理的数据库中间件;它和MyCat最大的不同是sharding-jdbc支持库内分表。

整合

数据库环境

在两台不同的主机上分别都创建了sharding_order数据库,库中都有t_order_1和t_order_2两张表。
SpringBoot整合Sharding-Jdbc实现分库分表和分布式全局id_第1张图片

sharding-jdbc依赖如下

        <dependency>
            <groupId>org.apache.shardingsphere</groupId>
            <artifactId>sharding-jdbc-spring-boot-starter</artifactId>
            <version>4.1.1</version>
        </dependency>

application.properties配置文件

在application.properties配置文件中进行数据源配置、分库分表规则配置

#shardingsphere数据源配置
spring.shardingsphere.datasource.names=ds0,ds1

#数据源配置
spring.shardingsphere.dataSource.ds0.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.dataSource.ds0.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.dataSource.ds0.jdbcUrl=jdbc:mysql://192.168.200.215:3306/sharding_order?serverTimezone=UTC&useSSL=false&useUnicode=true&characterEncoding=UTF-8
spring.shardingsphere.dataSource.ds0.username=root
spring.shardingsphere.dataSource.ds0.password=root

spring.shardingsphere.dataSource.ds1.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.dataSource.ds1.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.dataSource.ds1.jdbcUrl=jdbc:mysql://192.168.200.225:3306/sharding_order?serverTimezone=UTC&useSSL=false&useUnicode=true&characterEncoding=UTF-8
spring.shardingsphere.dataSource.ds1.username=root
spring.shardingsphere.dataSource.ds1.password=root


#shardingsphere数据节点分片规则
spring.shardingsphere.sharding.tables.t_order.actual-data-nodes=ds$->{0..1}.t_order_$->{1..2}

#数据源分片规则,决定数据落在哪个库
spring.shardingsphere.sharding.tables.t_order.database-strategy.inline.sharding-column=user_id
spring.shardingsphere.sharding.tables.t_order.database-strategy.inline.algorithm-expression=ds$->{user_id % 2}

#表分片规则,决定数据落在哪个表
spring.shardingsphere.sharding.tables.t_order.table-strategy.inline.sharding-column=id
spring.shardingsphere.sharding.tables.t_order.table-strategy.inline.algorithm-expression=t_order_$->{id % 2 + 1}

#逻辑表,mybatis中查询的时候需要使用逻辑表查询,不能使用具体的分片表
spring.shardingsphere.sharding.tables.t_order.logic-table=t_order

测试

    /**
     * 测试分库分表
     */
    @Test
    public void test4() {
        Order order = new Order();
        order.setId(5);
        order.setUserId(2);
        order.setOrderStatus(1);
        order.setOrderAmount(BigDecimal.valueOf(3000));
        orderMapper.insert(order);

    }

数据落在了215这台主机上的sharding_order数据库中的t_order_2表中;证明分库分表成功了。
SpringBoot整合Sharding-Jdbc实现分库分表和分布式全局id_第2张图片

分布式全局id设置

由于有两张order表,t_order_1和t_order2;而且在单表中我们往往会设置主键自增,那么就会出现表中的id重复的问题,sharding-jdbc支持使用通过雪花算法生成uuid作为主键来解决这个问题。

application.properties文件

#表分片规则
#标准表达式
spring.shardingsphere.sharding.tables.t_order.table-strategy.standard.sharding-column=id
spring.shardingsphere.sharding.tables.t_order.table-strategy.standard.precise-algorithm-class-name=com.sharding.jdbc.sharding.MySharding

#id生成规则,分布式全局id
spring.shardingsphere.sharding.tables.t_order.key-generator.column=id
spring.shardingsphere.sharding.tables.t_order.key-generator.type=UUID

分片规则

/**
 * @author DELL
 * @version 1.0
 * @description:精确分片规则
 * @date 2023/11/26 13:34:36
 */
public class MySharding implements PreciseShardingAlgorithm<String> {

    /**
     *
     * @param collection:表名
     * @param preciseShardingValue:生成的uuid、逻辑表、字段名
     * @return
     */
    @Override
    public String doSharding(Collection<String> collection, PreciseShardingValue<String> preciseShardingValue) {
        String id = preciseShardingValue.getValue();

        int mode = id.hashCode() % collection.size();

        String[] strings = collection.toArray(new String[0]);
        System.out.println("strings:" + Arrays.toString(strings));
        return strings[Math.abs(mode)];
    }
}

测试生成分布式id

这里要注意的是由于这里的id是sharding-jdbc帮我们生成的,所以调用mapper中方法的时候不能指定id,否则不会自动生成。

    /**
     * 测试生成uuid
     */
    @Test
    public void test5() {
        Order order = new Order();
        order.setUserId(3);
        order.setOrderStatus(1);
        order.setOrderAmount(BigDecimal.valueOf(3000));
        orderMapper.insert(order);
    }

如果报了这个错,大概率就是sql中指定了id。

Sharding value must implements Comparable.

uui的是有可能重复的,这里可以指定使用雪花算法生成uuid。雪花算法配置如下:

spring.shardingsphere.sharding.tables.t_order.key-generator.column=id
spring.shardingsphere.sharding.tables.t_order.key-generator.type=SNOWFLAKE
spring.shardingsphere.sharding.tables.t_order.key-generator.props.worker.id=345

分片规则中的String需要改成Long。

参考

  1. Sharding-JDBC官网-配置手册
  2. ShardingSphere报Sharding value must implements Comparable.的解决过程

你可能感兴趣的:(数据库,消息中间件,spring,boot,分布式,后端,mysql,java,java-ee)