ShardingSphere-Proxy5自定义算法
ShardingSphere 支持两种方式来扩展自定义算法:SPI 和 ClassBased。CLASS_BASE实际上是已经实现了的SPI。
ClassBased实现自定义分片
ClassBased需要我们实现StandardShardingAlgorithm接口。
创建springboot工程
首先创建一个springboot工程,并添加sharding-sphere依赖- <dependency>
- <groupId>org.apache.shardingsphere</groupId>
- <artifactId>shardingsphere-jdbc-core-spring-boot-starter</artifactId>
- <version>5.2.0</version>
- </dependency>
复制代码 新建自定义算法类
新建一个类DemoAlgortihm并实现StandardShardingAlgorithm接口。- public class DemoAlgortihm implements StandardShardingAlgorithm<Integer> {
-
- /**
- * 精确查询分片执行接口
- * @param availableTargetNames: 可用的分片名集合(分库就是库名,分表就是表名)
- * @param preciseShardingValue: 分片键
- * @return 分片名
- */
- @Override
- public String doSharding(Collection<String> availableTargetNames, PreciseShardingValue<Integer> preciseShardingValue) {
- // availableTargetNames: 分片集合
- // preciseShardingValue: 分片键值
- String logicTableName = preciseShardingValue.getLogicTableName();
- // 获取分片键value
- Integer userIdL = preciseShardingValue.getValue();
-
- // 实现 t_order$->{user_id % 2} BigInteger userId = BigInteger.valueOf(userIdL);
-
- BigInteger result = userId.mod(new BigInteger("2"));
- String key = logicTableName+""+result;
-
- if (availableTargetNames.contains(key)) {
- return key;
- }
-
- throw new UnsupportedOperationException("route: " + key + " is not supported, please check your config");
- }
-
- /**
- * 范围查询分片算法(分片键涉及区间查询时会进入该方法进行分片计算)
- * @param availableTargetNames
- * @param rangeShardingValue
- * @return 返回多个分片名
- */
- @Override
- public Collection<String> doSharding(Collection<String> availableTargetNames, RangeShardingValue<Integer> rangeShardingValue) {
- // 对于取模算法分片,无法确定查询区间里涉及的分片,因此直接返回所有路由
- return availableTargetNames;
- }
- // 自定义算法参数
- @Getter
- private Properties props;
-
- @Override
- public void init(Properties properties) {
- }
- }
复制代码 打包
打包放在sharding-proxy的lib目录。注意打包时不能使用springboot插件进行打包,打包后包结构一定要如下所示,否则无法正确找到自定义算法。这种形式的打包并不会引入依赖,因此如果自定义算法需要引入其他jar包时,我们要手动把依赖的包也一并放到sharding-proxy的lib目录。
![[Pasted image 20221011113051.png]]
配置分片规则
修改config-sharding.yaml文件添加数据分片规则- alg_hash_mod:
- # type: HASH_MOD
- # props:
- # sharding-count: 2
- type: CLASS_BASED
- props:
- strategy: standard # 我们实现的是StandardShardingAlgorithm接口,因此属于standard策略
- # 自定义算法全限定类名
- algorithmClassName: com.sharding.algortihm.DemoAlgortihm
复制代码 完整配置文件- databaseName: sharding_db
- dataSources:
- ds_0:
- url: jdbc:mysql://127.0.0.1:13307/demo_ds_0?serverTimezone=UTC&useSSL=false
- username: root
- password: sunday
- connectionTimeoutMilliseconds: 30000
- idleTimeoutMilliseconds: 60000
- maxLifetimeMilliseconds: 1800000
- maxPoolSize: 50
- minPoolSize: 1
- ds_1:
- url: jdbc:mysql://127.0.0.1:3306/demo_ds_1?serverTimezone=UTC&useSSL=false
- username: root
- password: sunday
- connectionTimeoutMilliseconds: 30000
- idleTimeoutMilliseconds: 60000
- maxLifetimeMilliseconds: 1800000
- maxPoolSize: 50
- minPoolSize: 1
- rules:
- - !SHARDING
- tables:
- t_order:
- actualDataNodes: ds_${0..1}.t_order${0..1}
- databaseStrategy:
- standard:
- shardingColumn: user_id
- shardingAlgorithmName: alg_mod
- tableStrategy:
- standard:
- shardingColumn: order_no
- shardingAlgorithmName: alg_hash_mod
- keyGenerateStrategy:
- column: id
- keyGeneratorName: snowflake
- keyGenerators:
- snowflake:
- type: SNOWFLAKE
- shardingAlgorithms:
- alg_mod:
- type: MOD
- props:
- sharding-count: 2
- alg_hash_mod:
- # type: HASH_MOD
- # props:
- # sharding-count: 2
- type: CLASS_BASED
- props: # 算法参数,可以在下面自定义自己的参数,获取时通过自定义算法中的props对象获取。参数值仅支持字符串和数字,不支持对象、map等参数,对于map等参数可以按照字符串形式传入程序,然后通过JSON工具反序列化。
- strategy: standard # 我们实现的是StandardShardingAlgorithm接口,因此属于standard策略
- # 自定义算法全限定类名
- algorithmClassName: com.sharding.algortihm.DemoAlgortihm
复制代码 连接proxy创建分片表
配置分片表后,并没有生成相应的分片表,需要连接上sharding-proxy,在proxy中执行建表语句,在创建逻辑表时分片表会被proxy自动按照配置的规则进行创建。- CREATE TABLE `t_order` (
- `id` bigint(20) NOT NULL AUTO_INCREMENT,
- `order_no` varchar(30) DEFAULT NULL,
- `user_id` bigint(20) DEFAULT NULL,
- `amount` decimal(10,2) DEFAULT NULL,
- PRIMARY KEY (`id`)
- ) ENGINE=InnoDB AUTO_INCREMENT=779468255126355969 DEFAULT CHARSET=utf8mb4;
复制代码 插入测试数据
- INSERT INTO `sharding_db`.`t_order`(`id`, `order_no`, `user_id`, `amount`) VALUES (779468213359476737, '22', 22, 22.00);
- INSERT INTO `sharding_db`.`t_order`(`id`, `order_no`, `user_id`, `amount`) VALUES (779468285585391617, '44', 44, 44.00);
- INSERT INTO `sharding_db`.`t_order`(`id`, `order_no`, `user_id`, `amount`) VALUES (779468168534949888, '11', 11, 11.00);
- INSERT INTO `sharding_db`.`t_order`(`id`, `order_no`, `user_id`, `amount`) VALUES (779468255126355968, '33', 33, 33.00);
复制代码 免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! |