【mk】sharding - Jdbc 分布式全局ID(雪花算法) Springboot 、 自定义分片策略

该博客介绍了如何在Spring中使用ShardingSphere进行数据分片,包括设置雪花算法作为主键生成策略,配置最大时钟回拨容忍毫秒数,以及实现自定义分片策略。示例展示了数据库表结构、appliaction.properties配置文件内容,以及Java测试代码,强调了在插入数据时无需设定id值,由ShardingSphere自动生成。
摘要由CSDN通过智能技术生成

UUID

uuid是生成32位长的字符串,一般作为ID ,不建议使用 字符串作为主键

SNOWFLAKE 雪花算法 配置

sharding-jdbc 可设置 最大容忍的时钟回拨毫秒数 , 超过这个时间就报错

1. 首先指定数据库中的哪个字段为主键

spring.shardingsphere.sharding.tables.shard.key-generator.column=id

2. 指定主键的生成策略

spring.shardingsphere.sharding.tables.shard.key-generator.type=SNOWFLAKE

3. 指定 工作机器数量 最大是2的10次方 , 即小于 1024 就可以 

spring.shardingsphere.sharding.tables.shard.key-generator.props.worker.id=1000

4. 雪花算法依据时间戳来生成的,一旦时间戳回拨就会造成 id 重复的可能

# 最大容忍的时钟回拨毫秒数
spring.shardingsphere.sharding.tables.shard.key-generator.max.tolerate.time.difference.milliseconds=5

数据库表结构如下:

 有两个数据库,分别是 test1、test2数据库,每个库里分别有shard_0、shard_1、shard_2   3张表。

CREATE TABLE `shard_0` (
  `id` bigint(20) NOT NULL,
  `name` varchar(255) DEFAULT NULL,
  `user_id` bigint(20) DEFAULT NULL,
  `remark` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;

 appliaction.properties 

server.port=8088
#[-----------------------------------------------------------雪花算法 配置-----------------------------------------------------------------]
# 【配置真实数据源】
spring.shardingsphere.datasource.names=ds0,ds1

# 【配置第 1 个数据源】
spring.shardingsphere.datasource.ds0.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.ds0.driver-class-name=com.mysql.cj.jdbc.Driver
spring.shardingsphere.datasource.ds0.jdbc-url=jdbc:mysql://localhost/test1?characterEncoding=utf-8&serverTimezone=UTC
spring.shardingsphere.datasource.ds0.username=root
spring.shardingsphere.datasource.ds0.password=123456

# 【配置第 2 个数据源】
spring.shardingsphere.datasource.ds1.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.ds1.driver-class-name=com.mysql.cj.jdbc.Driver
spring.shardingsphere.datasource.ds1.jdbc-url=jdbc:mysql://localhost:3306/test2?characterEncoding=utf-8&serverTimezone=UTC
spring.shardingsphere.datasource.ds1.username=root
spring.shardingsphere.datasource.ds1.password=123456

# ⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐ 【配置分库策略】

##    shard 数据库分片键 : user_id
spring.shardingsphere.sharding.tables.shard.database-strategy.inline.sharding-column=user_id
spring.shardingsphere.sharding.tables.shard.database-strategy.inline.algorithm-expression=ds$->{user_id % 2}


# ⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐ 【配置分表策略】

spring.shardingsphere.sharding.tables.shard.actual-data-nodes=ds$->{0..1}.shard_$->{0..2}
spring.shardingsphere.sharding.tables.shard.table-strategy.inline.sharding-column=id
spring.shardingsphere.sharding.tables.shard.table-strategy.inline.algorithm-expression=shard_$->{id % 3}



# ⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐ 【指定ID生成策略】
spring.shardingsphere.sharding.tables.shard.key-generator.column=id
spring.shardingsphere.sharding.tables.shard.key-generator.type=SNOWFLAKE
#小于 1024 即可
spring.shardingsphere.sharding.tables.shard.key-generator.props.worker.id=1000
# 最大容忍的时钟回拨毫秒数
spring.shardingsphere.sharding.tables.shard.key-generator.props.max.tolerate.time.difference.milliseconds=5

Spring 测试代码 

  @Test
    public  void shardInsert(){
        Shard shard = new Shard();

        shard.setName("67");
        shard.setUserId(23L);
        shard.setRemark("87saf");
        int result = shardMapper.save(shard);
        System.err.println("插入结果 : "+ result);
}

⭐⭐⭐
【shard 表的主键是 id ,但是在插入的时候不需要设定 id 的值, sharding会自动生成】
【同时sql 中也不需要 插入id 字段】



public class Shard implements Serializable {
    private Long id;

    private String name;

    private Long userId;

    private String remark;



【同时sql 中也不需要 插入id 字段】

 <insert id="save">
    insert into shard ( `name`, user_id, remark)
    values ( #{name,jdbcType=VARCHAR}, 
            #{userId,jdbcType=BIGINT},
            #{remark,jdbcType=VARCHAR})

  </insert>

自定义分片策略 

自定义分片策略,配置需要改动。同样,

1. 也是需要先定义哪个字段来分片,

2. 然后使用自定义的分片策略,把全路径赋值过来

 application.properties 中更改的部分就是这一块

# ⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐  【配置分表策略】
spring.shardingsphere.sharding.tables.shard.actual-data-nodes=ds$->{0..1}.shard_$->{0..2}
 #   这是老的方式
#spring.shardingsphere.sharding.tables.shard.table-strategy.inline.sharding-column=id
#spring.shardingsphere.sharding.tables.shard.table-strategy.inline.algorithm-expression=shard_$->{id % 3}
#   这是自定义分片策略
spring.shardingsphere.sharding.tables.shard.table-strategy.standard.sharding-column=id
# precise-algorithm-class-name:精准表达式类名 用于等于 in 这种语句中;  range-algorithm-class-name:范围,用于 between
spring.shardingsphere.sharding.tables.shard.table-strategy.standard.precise-algorithm-class-name=com.example.shardingjdbc.sharding.MySharding

  这是自定义的 分片策略

package com.example.shardingjdbc.sharding;

import org.apache.shardingsphere.api.sharding.standard.PreciseShardingAlgorithm;
import org.apache.shardingsphere.api.sharding.standard.PreciseShardingValue;
import org.springframework.stereotype.Component;

import java.util.Collection;
@Component
public class MySharding implements PreciseShardingAlgorithm<Long> {
     //  <Long>  是因为 id 是 long 类型

    @Override
    public String doSharding(Collection<String> collection, PreciseShardingValue<Long> preciseShardingValue) {
        Long id = (Long) preciseShardingValue.getValue();
        // 如果 id 是 string ,可以 id.hashcode()
       int model = (int) (id % collection.size());
        model = Math.abs(model); // 取绝对值

        System.err.println("collection.size() : "+collection.size());
        System.err.println("model : "+model);
        String[] strings =  collection.toArray(new String[0]);
        System.err.println(strings[0]  +"  " + strings[1]+"  " + strings[2]);

        return strings[model];
    }


}

=======================================
console打印结果 : 
collection.size() : 3       collection 这里就是所有表的集合,一个库是3张表,所有是3
model : 2
shard_0  shard_1  shard_2

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值