shardingsphere-雪花算法

雪花算法

  • 雪花算法默认配置
  • 具体表的雪花算法配置
    • 关于worker.id
  • 雪花算法封装成工具类
  • 雪花算法对batchInsert路由的影响
    • batchInsert开启雪花算法自动生成
    • batchInsert不使用雪花算法
  • 使用pg大小写对雪花算法的影响

雪花算法默认配置

spring.shardingsphere.sharding.default-key-generator.column=id
spring.shardingsphere.sharding.default-key-generator.type=SNOWFLAKE
spring.shardingsphere.sharding.default-key-generator.props.worker.id=123

具体表的雪花算法配置

spring.shardingsphere.sharding.tables.device.key-generator.column=id
spring.shardingsphere.sharding.tables.device.key-generator.type=SNOWFLAKE
spring.shardingsphere.sharding.tables.device.key-generator.props.worker.id=123

关于worker.id

如果只配置key-generator.column 和key-generator.type的话,不配置worker.id 则在进行真正计算时会使用雪花内部的默认值即worker.id=0来计算, 他并不会使用default里配置的默认值的worker.id

spring.shardingsphere.sharding.default-key-generator.props.worker.id=123

雪花算法封装成工具类

可以将雪花算法封装成工具类,任意一个程序都可以调用该工具类返回一个键

import org.apache.shardingsphere.core.strategy.keygen.SnowflakeShardingKeyGenerator;
public class SnowFlakeUtils {
    public static Comparable  getId(Long workerId) {
        if (!(workerId >= 0 && workerId < 1024L)) {
            throw new RuntimeException(String.format("workerId is not support range must be [0,1024)"));
        }
        SnowflakeShardingKeyGenerator snowflakeShardingKeyGenerator = new SnowflakeShardingKeyGenerator();
        snowflakeShardingKeyGenerator.getProperties().put("worker.id", String.valueOf(workerId));
        Comparable generateKey = snowflakeShardingKeyGenerator.generateKey();
        return generateKey;
    }
}

具体的使用为

@Test
    public void test02() {
        ShardingDataSource shardingDataSource =(ShardingDataSource) SpringContextUtils.getBean("shardingDataSource");
        //可以取默认的id也可以取某个表的id
        String workerId = shardingDataSource.getRuntimeContext().getRule().getDefaultShardingKeyGenerator().getProperties().getProperty("worker.id");
        Comparable id = SnowFlakeUtils.getId(Long.parseLong(workerId));
        System.out.println(id);
    }

雪花算法对batchInsert路由的影响

batchInsert开启雪花算法自动生成

shardingsphere的问题描述
4.0.0 与 4.0.1都会存在问题
如果使用雪花算法,并且使用batchInsert时,并且库的分片键,与表的分片键不同例如库为user_id 表为id进行分片时
结果为: db与tb的最终都是以user_id来算出表后缀,即最终会往不正确的路由表结果里插入数据,但是不会报错

例如
shardingsphere-雪花算法_第1张图片
如果库与表的取模分片键相同 并且取模算法也相同 能够恰好避免隐藏掉这个问题 都以id取模 都对2取模 比如id=10 库与表的取模结果都为 ds0.rice_0 虽然结果正确 ,但是因为取模都相同导致的

batchInsert不使用雪花算法

如果批量插入并且不使用雪花算法,则最终无论库表分片键是否相同,分片算法是否一致 路由结果都是非常准确的 可以放心的用
这个我自己经过测试没问题的

2020-07-06 22:21:39.444  INFO 24672 --- [           main] ShardingSphere-SQL                       : Actual SQL: ds0 ::: insert into complex_rice_1 ( id,name,user_id ) values (?, ?, ?), (?, ?, ?), (?, ?, ?) ::: [486994431724466295, 五常0, 0, 486994431724466293, 五常2, 2, 486994431724466291, 五常4, 4]
2020-07-06 22:21:39.444  INFO 24672 --- [           main] ShardingSphere-SQL                       : Actual SQL: ds0 ::: insert into complex_rice_0 ( id,name,user_id ) values (?, ?, ?) ::: [486994431724466396, 五常0, 0]
2020-07-06 22:21:39.444  INFO 24672 --- [           main] ShardingSphere-SQL                       : Actual SQL: ds1 ::: insert into complex_rice_0 ( id,name,user_id ) values (?, ?, ?), (?, ?, ?) ::: [486994431724466294, 五常1, 1, 486994431724466292, 五常3, 3]
2020-07-06 22:21:39.446  INFO 24672 --- [           main] ShardingSphere-SQL                       : Actual SQL: ds1 ::: insert into complex_rice_1 ( id,name,user_id ) values (?, ?, ?) ::: [486994431724466395, 五常1, 1]
2020-07-06 22:21:40.336  INFO 24672 --- [       Thread-3] com.alibaba.druid.pool.DruidDataSource   : {dataSource-1} closed
2020-07-06 22:21:40.337  INFO 24672 --- [       Thread-3] com.alibaba.druid.pool.DruidDataSource   : {dataSource-2} closed

使用pg大小写对雪花算法的影响

由于pg会对大小进行双引号,即如果大写的ID要带"" 即"ID" ,如果写成ID在进行访问时就会被数据库驱动改写成id ,从而最后报一个没有该id的列,而实际上数据库是一个""

你可能感兴趣的:(shardingsphere-雪花算法)