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
如果只配置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);
}
shardingsphere的问题描述
4.0.0 与 4.0.1都会存在问题
如果使用雪花算法,并且使用batchInsert时,并且库的分片键,与表的分片键不同例如库为user_id 表为id进行分片时
结果为: db与tb的最终都是以user_id来算出表后缀,即最终会往不正确的路由表结果里插入数据,但是不会报错
例如
如果库与表的取模分片键相同 并且取模算法也相同 能够恰好避免隐藏掉这个问题 都以id取模 都对2取模 比如id=10 库与表的取模结果都为 ds0.rice_0 虽然结果正确 ,但是因为取模都相同导致的
如果批量插入并且不使用雪花算法,则最终无论库表分片键是否相同,分片算法是否一致 路由结果都是非常准确的 可以放心的用
这个我自己经过测试没问题的
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会对大小进行双引号,即如果大写的ID要带"" 即"ID" ,如果写成ID在进行访问时就会被数据库驱动改写成id ,从而最后报一个没有该id的列,而实际上数据库是一个""