sharding-jdbc 5.1.1 分库分表(基于spring-boot 2.6.7)

前言

1.主要对sharding-jdbc 5.1.1 版本分片策略算法进行技术学习
2.对spring-boot 2.6.7及以上版本、mybatis-plus 3.5.1版本进行整合



一、maven依赖


        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>
        
        <dependency>
            <groupId>org.apache.shardingsphere</groupId>
            <artifactId>shardingsphere-jdbc-core-spring-boot-starter</artifactId>
            <version>5.1.1</version>
        </dependency>

        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.5.1</version>
        </dependency>

		<dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
        
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.13</version>
        </dependency>

二、创建数据库表

create table act_order_x
(
    id               bigint(32)        not null comment '主键id'
        primary key,
    req_id           bigint(32)        not null comment '请求流水号',
    order_type       varchar(8)        null comment '订单类型',
    order_amount     decimal(10, 2)    null comment '订单金额',
    mer_id           varchar(16)       null comment '商户号',
    create_date_time timestamp         null comment '创建时间',
    update_date_time timestamp         null comment '修改时间',
    is_delete        tinyint default 0 null comment '删除'
);

create table act_order_yyyyMMdd
(
    id               bigint(32)        not null comment '主键id'
        primary key,
    req_id           bigint(32)        not null comment '请求流水号',
    order_type       varchar(8)        null comment '订单类型',
    order_amount     decimal(10, 2)    null comment '订单金额',
    mer_id           varchar(16)       null comment '商户号',
    create_date_time timestamp         null comment '创建时间',
    update_date_time timestamp         null comment '修改时间',
    is_delete        tinyint default 0 null comment '删除'
);

三、数据源配置

数据源名称(可以理解为别名)
spring.shardingsphere.datasource.names=ds0,ds1
#数据源1
spring.shardingsphere.datasource.ds0.type=com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.ds0.driver-class-name=com.mysql.cj.jdbc.Driver
spring.shardingsphere.datasource.ds0.url=jdbc:mysql://127.0.0.1:3306/ds_account_0?characterEncoding=utf8&serverTimezone=Asia/Shanghai
spring.shardingsphere.datasource.ds0.username=root
spring.shardingsphere.datasource.ds0.password=root
#数据源2
spring.shardingsphere.datasource.ds1.type=com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.ds1.driver-class-name=com.mysql.cj.jdbc.Driver
spring.shardingsphere.datasource.ds1.url=jdbc:mysql://127.0.0.1:3306/ds_account_1?characterEncoding=utf8&serverTimezone=Asia/Shanghai
spring.shardingsphere.datasource.ds1.username=root
spring.shardingsphere.datasource.ds1.password=root

1.库表的生成策略

1.1库策略

sharding-column 为以写入值进行分库策略,分库算法以后面分片策略为准

#自动分片对应策略
spring.shardingsphere.rules.sharding.default-database-strategy.standard.sharding-column=id
spring.shardingsphere.rules.sharding.default-database-strategy.standard.sharding-algorithm-name=db-inline
#复合分片对应策略
spring.shardingsphere.rules.sharding.default-database-strategy.complex.sharding-columns=id,req_id
spring.shardingsphere.rules.sharding.default-database-strategy.complex.sharding-algorithm-name=db-inline
#Hint(强制路由对应策略
spring.shardingsphere.rules.sharding.default-database-strategy.hint.sharding-algorithm-name=id

1.2表策略

1.2.1单库多表指定
#ds0库.act_order_0-5表
spring.shardingsphere.rules.sharding.tables.act_order.actual-data-nodes=ds0.act_order_$->{0..5}
#以id值作为算法数值
spring.shardingsphere.rules.sharding.tables.act_order.table-strategy.standard.sharding-column=id
#对表act_order 设定算法别名
spring.shardingsphere.rules.sharding.tables.act_order.table-strategy.standard.sharding-algorithm-name=t-order-inline
1.2.2多库多表指定
#ds0-1库.act_order_0-5表
spring.shardingsphere.rules.sharding.tables.act_order.actual-data-nodes=ds$->{0..1}.act_order_$->{0..5}
#以id值作为算法数值
spring.shardingsphere.rules.sharding.tables.act_order.table-strategy.standard.sharding-column=id
#对表act_order 设定算法别名
spring.shardingsphere.rules.sharding.tables.act_order.table-strategy.standard.sharding-algorithm-name=t-order-inline

2.id生成策略

2.1使用sharding自带算法生成id

act_order为逻辑表

#以id为策略进行分表
spring.shardingsphere.rules.sharding.tables.act_order.key-generate-strategy.column=id
#可以理解为别名
spring.shardingsphere.rules.sharding.tables.act_order.key-generate-strategy.key-generator-name=snowflake
#sharding自带算法  指定算法
spring.shardingsphere.rules.sharding.key-generators.snowflake.type=SNOWFLAKE
#最大抖动上限值,范围[0, 4096)
spring.shardingsphere.rules.sharding.key-generators.snowflake.props.max-vibration-offset=1
#最大容忍时钟回退时间
spring.shardingsphere.rules.sharding.key-generators.snowflake.props.max-tolerate-time-difference-milliseconds=10
@Data
@TableName("act_order")
public class Order implements Serializable {

    private static final long serialVersionUID = 1L;

    /**
     * 主键id 如果使用mybatis-plus的话,注释掉@TableId否则无效
     */
//	@TableId(type = IdType.AUTO) 
    private Long id;

四、分片策略

1.自动分片策略算法

1.1 取模分片算法

#分库策略算法
spring.shardingsphere.rules.sharding.sharding-algorithms.db-inline.type=MOD
spring.shardingsphere.rules.sharding.sharding-algorithms.db-inline.props.sharding-count=2
#取模分片算法
spring.shardingsphere.rules.sharding.sharding-algorithms.t-order-inline.type=MOD
spring.shardingsphere.rules.sharding.sharding-algorithms.t-order-inline.props.sharding-count=5

1.2 哈希取模分片算法

#分库策略算法
spring.shardingsphere.rules.sharding.sharding-algorithms.db-inline.type=HASH_MOD
spring.shardingsphere.rules.sharding.sharding-algorithms.db-inline.props.sharding-count=2
#分表策略算法
spring.shardingsphere.rules.sharding.sharding-algorithms.t-order-inline.type=HASH_MOD
spring.shardingsphere.rules.sharding.sharding-algorithms.t-order-inline.props.sharding-count=5

1.3 基于分片容量的范围分片算法

# id从1自增 l=50 u=100 v=5  t=150 order0(1-49) order1(50-54) order2(55-59) order3(60-64) order4(65-69) 报异常
# id从1自增 l=50 u=100 v=10 t=150 order0(1-49) order1(50-59) order2(60-69) order3(70-79) order4(80-89) 报异常
# id从1自增 l=50 u=100 v=20 t=150 order0(1-49) order1(50-69) order2(70-89) order3(90-99) order4(100-150) 没有异常 没有对id进行限制
# id从51自增 l=50 u=100 v=15 t=150 order0(null) order1(51-64) order2(65-79) order3(80-94) order4(95-99) 报异常 对id 进行限制?
# id从51自增 l=50 u=100 v=20 t=150 order0(null) order1(51-69) order2(70-89) order3(90-99) order4(100-200) 没有异常 没有对id进行限制
# 是否是只要满足了 l-u区间的数量分配 后面就不会异常
# id从51自增 l=50 u=100 v=25 t=150 order0(null) order1(51-74) order2(75-99) order3(100-200) order4(null) 没有异常 没有对id进行限制
# id改为雪花算法 条件不变
# id改为雪花算法 l=50 u=100 v=25 t=150 order0(null) order1(null) order2(null) order3(150) order4(null) 没有异常 没有对id进行限制
# id改为雪花算法 l=50 u=100 v=20 t=150 order0(null) order1(null) order2(null) order3(null) order4(150) 没有异常 没有对id进行限制
# id改为雪花算法 l=50 u=100 v=15 t=150 直接报异常
# 是否与表数量有关系 增加一张order_5表
# id改为雪花算法 l=50 u=100 v=15 t=150 order0(null) order1(null) order2(null) order3(null) order4(null) order5(150) 没有异常
# id改为雪花算法  l=50 u=100 v=10 t=150 直接报异常
# 修改 范围下界0 范围上界25
# id改为雪花算法  l=0 u=25 v=10 t=100 order0(null) order1(null) order2(null) order3(null) order4(100) order5(null) 没有异常
# id改为雪花算法  l=0 u=60 v=10 t=100 直接报异常
# id改为雪花算法  l=0 u=40 v=10 t=100 order0(null) order1(null) order2(null) order3(null) order4(100) order5(null)
# id改为雪花算法  l=0 u=41 v=10 t=100 直接报异常
# 总结
# 1.假如有6张表  范围0-40 那么去头表尾表的数量 * sharding-volume(10)<= 40 不会报错
# 2.对数据的限制  long 类型  其他类型报错  浮点类型为尝试
spring.shardingsphere.rules.sharding.sharding-algorithms.t-order-inline.type=VOLUME_RANGE
spring.shardingsphere.rules.sharding.sharding-algorithms.t-order-inline.props.range-lower=0
spring.shardingsphere.rules.sharding.sharding-algorithms.t-order-inline.props.range-upper=40
spring.shardingsphere.rules.sharding.sharding-algorithms.t-order-inline.props.sharding-volume=10

1.4 基于分片边界的范围分片算法

#id为雪花算法 20,40,60,80,100 t=100 order0(null) order1(null) order2(null) order3(null) order4(null) order5(100)
#id从1自增   20,40,60,80,100 t=100 order0(1-19) order1(20-39) order2(40-59) order3(60-79) order4(80-99) order5(100)
#id从1自增   20,40,60,80,100 t=150 order0(1-19) order1(20-39) order2(40-59) order3(60-79) order4(80-99) order5(100-150)
spring.shardingsphere.rules.sharding.sharding-algorithms.t-order-inline.type=BOUNDARY_RANGE
spring.shardingsphere.rules.sharding.sharding-algorithms.t-order-inline.props.sharding-ranges=20,40,60,80,100

1.5 自动时间分片

根据时间范围自动散落到各表中
order_0 date < 2022-05-01 00:00:00
order_5 date > 2022-05-31 23:59:59

spring.shardingsphere.rules.sharding.tables.act_order.table-strategy.standard.sharding-column=create_date_time
spring.shardingsphere.rules.sharding.tables.act_order.table-strategy.standard.sharding-algorithm-name=t-order-inline
spring.shardingsphere.rules.sharding.sharding-algorithms.t-order-inline.type=AUTO_INTERVAL
spring.shardingsphere.rules.sharding.sharding-algorithms.t-order-inline.props.datetime-lower=2022-05-01 00:00:00
spring.shardingsphere.rules.sharding.sharding-algorithms.t-order-inline.props.datetime-upper=2022-05-31 23:59:59
spring.shardingsphere.rules.sharding.sharding-algorithms.t-order-inline.props.sharding-seconds=86400

2.标准分片策略算法

1. 行表达式分片算法

spring.shardingsphere.rules.sharding.sharding-algorithms.db-inline.type=INLINE
spring.shardingsphere.rules.sharding.sharding-algorithms.db-inline.props.algorithm-expression=ds$->{id % 2}
spring.shardingsphere.rules.sharding.sharding-algorithms.t-order-inline.type=INLINE
spring.shardingsphere.rules.sharding.sharding-algorithms.t-order-inline.props.algorithm-expression=act_order_$->{id % 5}

2. 时间范围分片算法

spring.shardingsphere.rules.sharding.tables.act_order.actual-data-nodes=ds0.act_order_$->{20220520..20220531}
spring.shardingsphere.rules.sharding.tables.act_order.table-strategy.standard.sharding-column=create_date_time
spring.shardingsphere.rules.sharding.tables.act_order.table-strategy.standard.sharding-algorithm-name=t-order-inline
spring.shardingsphere.rules.sharding.sharding-algorithms.t-order-inline.type=INTERVAL
spring.shardingsphere.rules.sharding.sharding-algorithms.t-order-inline.props.datetime-pattern=yyyy-MM-dd HH:mm:ss
spring.shardingsphere.rules.sharding.sharding-algorithms.t-order-inline.props.datetime-lower=2022-01-01 00:00:00
spring.shardingsphere.rules.sharding.sharding-algorithms.t-order-inline.props.datetime-upper=2030-12-01 00:00:00
spring.shardingsphere.rules.sharding.sharding-algorithms.t-order-inline.props.sharding-suffix-pattern=yyyyMMdd
spring.shardingsphere.rules.sharding.sharding-algorithms.t-order-inline.props.datetime-interval-amount=1
spring.shardingsphere.rules.sharding.sharding-algorithms.t-order-inline.props.datetime-interval-unit=DAYS

3.复合分片策略算法

复合分片算法 配置策略的时候要配置 complex
支持多个分片键并且使用行表达式来分片,假设使用主键id 和reqId 来分片

spring.shardingsphere.rules.sharding.tables.act_order.table-strategy.complex.sharding-columns=id,req_id
spring.shardingsphere.rules.sharding.tables.act_order.table-strategy.complex.sharding-algorithm-name=t-order-inline
spring.shardingsphere.rules.sharding.sharding-algorithms.t-order-inline.type=COMPLEX_INLINE
spring.shardingsphere.rules.sharding.sharding-algorithms.t-order-inline.props.sharding-columns=id,req_id
spring.shardingsphere.rules.sharding.sharding-algorithms.t-order-inline.props.algorithm-expression=act_order_$->{(id % 2) + (req_id % 2)}
spring.shardingsphere.rules.sharding.sharding-algorithms.t-order-inline.props.allow-range-query-with-inline-sharding=true

4.Hint分片策略算法

强制路由算法,在其他的算法中需要从sql中解析出对应的分片键和值,而这个算法是通过API强制设置的方式;
通过inline 表达式和 Api 来实现一个分片算法;
在此配置中,策略为 hint ,不用指定分片键,不从数据中解析分片信息,而是通过一个Api;
HintManager 通过 addTableShardingValue 和 addDatabaseShardingValue来设置表分片的value 和库分片的value ,在执行数据分片的解析表达式的时候从这个手动设置的值中获取;

spring.shardingsphere.rules.sharding.tables.act_order.actual-data-nodes=ds0.act_order_$->{0..5}
spring.shardingsphere.rules.sharding.tables.act_order.table-strategy.hint.sharding-algorithm-name=t-order-inline
#指定算法类型
spring.shardingsphere.rules.sharding.sharding-algorithms.t-order-inline.type=HINT_INLINE
spring.shardingsphere.rules.sharding.sharding-algorithms.t-order-inline.props.algorithm-expression=act_order_$->{value % 2}
    @Test
    public void hintInlineInsert() {
        HintManager hitManager = HintManager.getInstance();
        int num = 10000;
        for (int i = 0; i < 10; i++) {
            hitManager.addTableShardingValue("act_order", i);
            AtomicInteger atomicInteger = new AtomicInteger(num);
            Order order = new Order();
            order.setReqId(IdUtil.getSnowflake(1, 1).nextId());
            order.setOrderType("wx");
            order.setMerId("M" + String.valueOf(atomicInteger.addAndGet(i)));
            order.setOrderAmount(new BigDecimal("0.01"));
            order.setCreateDateTime(new Date());
            order.setUpdateDateTime(new Date());
            orderDao.insert(order);
            hitManager.clearShardingValues();
        }
    }

5.自定义分片策略算法

自定义分片策略算法使用SPI接口实现
在项目resources目录下创建META-INF.services目录
创建 org.apache.shardingsphere.sharding.spi.KeyGenerateAlgorithm id算法SPI接口
引入自定义算法的接口实现路径
在这里插入图片描述
在这里插入图片描述

1.自定义id算法

public class SnowFlakeShardingKeyGenerator implements KeyGenerateAlgorithm {

    private static final Logger LOGGER = LoggerFactory.getLogger(SnowFlakeShardingKeyGenerator.class);

    @Override
    public Comparable<?> generateKey() {
        long snowId = new SnowFlakeUtil(5, 6).nextId();
        return snowId;
    }

    @Override
    public void init() {}

    @Override
    public String getType() {
        LOGGER.info("ooxx");
        return "xxoo";
    }
}

2.自定义标准算法

创建org.apache.shardingsphere.sharding.spi.ShardingAlgorithm 自定义SPI算法接口
在这里插入图片描述
引入定义算法的实现路径
在这里插入图片描述

spring.shardingsphere.rules.sharding.tables.act_order.actual-data-nodes=ds0.act_order_$->{0..5}
spring.shardingsphere.rules.sharding.tables.act_order.table-strategy.standard.sharding-column=order_amount
spring.shardingsphere.rules.sharding.tables.act_order.table-strategy.standard.sharding-algorithm-name=t-order-inline
spring.shardingsphere.rules.sharding.sharding-algorithms.t-order-inline.type=STANDARD-AMOUNT
spring.shardingsphere.rules.sharding.sharding-algorithms.t-order-inline.props.sharding-count=3

3.自定义复合分片

#分库策略
spring.shardingsphere.rules.sharding.default-database-strategy.complex.sharding-columns=order_type
spring.shardingsphere.rules.sharding.default-database-strategy.complex.sharding-algorithm-name=t-db
#分表策略
spring.shardingsphere.rules.sharding.tables.act_order.actual-data-nodes=ds$->{0..1}.act_order_$->{0..5}
spring.shardingsphere.rules.sharding.tables.act_order.table-strategy.complex.sharding-columns=id,req_id
spring.shardingsphere.rules.sharding.tables.act_order.table-strategy.complex.sharding-algorithm-name=t-order
# 指定算法参数 类型
spring.shardingsphere.rules.sharding.sharding-algorithms.t-db.type=COMPLEX-DEMO
spring.shardingsphere.rules.sharding.sharding-algorithms.t-db.props.sharding-colums=order_type
spring.shardingsphere.rules.sharding.sharding-algorithms.t-order.type=COMPLEX-DEMO
spring.shardingsphere.rules.sharding.sharding-algorithms.t-order.props.sharding-columns=id,req_id

4.自定义Hint分片

spring.shardingsphere.rules.sharding.tables.act_order.actual-data-nodes=ds0.act_order_$->{0..5}
spring.shardingsphere.rules.sharding.tables.act_order.table-strategy.hint.sharding-algorithm-name=t-order-inline
spring.shardingsphere.rules.sharding.sharding-algorithms.t-order-inline.type=HINT-DEMO

五、公共表

1.广播表

##广播表 枚举表 部分表 多库的情况下  一次写入全体更新  解决问题:避免跨库查询影响效率
spring.shardingsphere.rules.sharding.broadcast-tables=act_dict
spring.shardingsphere.rules.sharding.tables.act_dict.key-generate-strategy.column=id
spring.shardingsphere.rules.sharding.tables.act_dict.key-generate-strategy.key-generator-name=snowflake

2.绑定表

#解决问题:关联查询优化 两张表进行关联查询 如果不绑定 则执行多条查询语句 如果设定绑定表关系则减少查询
spring.shardingsphere.rules.sharding.binding-tables=act_order,act_order_record

六、运行模式

1.模式的概念与应用场景

1.1内存模式(Memory)

默认的运行模式,用户无需配置 mode。内存模式下用户无需配置任何持久化组件和策略,无论是本地初始化的配置还是通过 SQL/DistSQL 操作造成的元数据变更,仅在当前进程中生效,服务重启后配置将会被还原。内存模式适用于集成测试环境,方便开发人员在整合功能测试中集成 ShardingSphere 而无需清理运行痕迹。

spring.shardingsphere.mode.type=Memory

1.2单机模式(Standalone)

ShardingSphere 为单机模式默认提供了本地文件的持久化方式,能够将数据源和规则等元数据信息持久化到本地文件中,而在服务重启的时候,依然能够从本地文件中读取配置,保持元数据和重启之前的版本一致。单机模式适用于开发工程师在本地快速搭建 ShardingSphere 的开发环境,进行功能的联调和验证。

spring.shardingsphere.mode.type=Standalone
# 持久化仓库类型
spring.shardingsphere.mode.repository.type= 
# 持久化仓库所需属性
spring.shardingsphere.mode.repository.props.<key>=
# 是否使用本地配置覆盖持久化配置
spring.shardingsphere.mode.overwrite= 

1.3集群模式(Cluster)

集群模式是 ShardingSphere 建议的真实部署上线的生产环境必须使用的模式,采用 JDBC 和 Proxy 混合部署架构也必须使用集群模式。集群模式提供了分布式治理的功能,通过集成独立部署的第三方注册中心,除了能够持久化元数据之外,同时实现了多个实例之间的数据共享以及分布式场景下的状态协调,也是 ShardingSphere 通过水平扩展来提高计算能力以及高可用等核心功能的基础。

spring.shardingsphere.mode.type=Cluster
# 持久化仓库类型
spring.shardingsphere.mode.repository.type= 
# 注册中心命名空间
spring.shardingsphere.mode.repository.props.namespace= 
# 注册中心连接地址
spring.shardingsphere.mode.repository.props.server-lists= 
# 持久化仓库所需属性
spring.shardingsphere.mode.repository.props.<key>= 
# 是否使用本地配置覆盖持久化配置
spring.shardingsphere.mode.overwrite= 

技术参考

[1]https://blog.csdn.net/qq_34279995/article/details/122421989
[2]https://shardingsphere.apache.org/document/current/cn/user-manual/shardingsphere-jdbc/builtin-algorithm/sharding/
[3]https://blog.csdn.net/ShardingSphere/article/details/122138311

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值