首页>>后端>>java->sharding

sharding

时间:2023-11-29 本站 点击:44

sharding-jdbc行分片策略默认不支持按分片键的范围查询

在开发时,对主键id做了 范围查询。结果遇到如下报错:

Errorqueryingdatabase.Cause:java.lang.IllegalStateException:Inlinestrategycannotsupportrangesharding.

原因:使用行分片策略

原先的sharding-jdbc的分片策略配置是:

sharding:binding-tables:tableNametables:tableName:actual-data-nodes:ds0.tableName_$->{0..1}table-strategy:inline:sharding-column:idalgorithm-expression:tableName_$->{id%2}

上面的配置,使用了主键id作为单分片键,行表达式的分片策略。该分片策略只支持 = 和 in 操作符,并不支持范围查询。如果你想要使用范围查询,你需要配置 开启标准策略。

解决方案:使用标准分片策略

对应配置:

sharding:binding-tables:tableNametables:tableName:table-strategy:standard:#用于单分片键的标准分片场景sharding-column:id#分片列名称precise-algorithm-class-name:com.project.com.PreciseModuloAlgorithm#精确分片算法类名称,用于=和IN。。该类需实现PreciseShardingAlgorithm接口并提供无参数的构造器range-algorithm-class-name:com.project.com.component.RangeModuloAlgorithm#范围分片算法类名称,用于BETWEEN,可选。该类需实现RangeShardingAlgorithm接口并提供无参数的构造器

问题具体可参考,官方github上的issues提问:https://github.com/apache/shardingsphere/issues/4180

其他配置可参考:https://shardingsphere.apache.org/document/legacy/4.x/document/cn/manual/sharding-jdbc/configuration/config-yaml/

对于具体的分片算法类,可参考官方github上的example:https://github.com/apache/shardingsphere-example

分片算法类 需要自己根据实际场景进行开发,这里贴出官方example里的实现类:

publicfinalclassPreciseModuloAlgorithmimplementsPreciseShardingAlgorithm<Integer>{@OverridepublicStringdoSharding(finalCollection<String>availableTargetNames,finalPreciseShardingValue<Integer>shardingValue){for(Stringeach:availableTargetNames){if(each.endsWith(shardingValue.getValue()%10+"")){returneach;}}thrownewUnsupportedOperationException();}}publicfinalclassRangeModuloAlgorithmimplementsRangeShardingAlgorithm<Integer>{@OverridepublicCollection<String>doSharding(finalCollection<String>availableTargetNames,finalRangeShardingValue<Integer>shardingValue){Collection<String>result=newLinkedHashSet<>(availableTargetNames.size());intminValue=shardingValue.getValueRange().hasLowerBound()?shardingValue.getValueRange().lowerEndpoint():Integer.MIN_VALUE;intmaxValue=shardingValue.getValueRange().hasUpperBound()?shardingValue.getValueRange().upperEndpoint():Integer.MAX_VALUE;//最大值减最小值,得到差longrange=BigInteger.valueOf(maxValue).subtract(BigInteger.valueOf(minValue)).longValue();//最小值得绝对值除10的余数intbegin=Math.abs(minValue)%10;//超过9直接返回可用的表名,这里的9是,自己的分片策略值//假设我的分片策略是:对id除以10,取余数if(range>9){returnavailableTargetNames;}//如果差在分片策略内的,就直接取余数,得到对应的表名for(inti=begin;i<=range;i+=1){for(Stringeach:availableTargetNames){if(each.endsWith(i+"")){result.add(each);}}}returnresult;}}

sharding-jdbc 分片策略

分片策略

包含分片键和分片算法,由于分片算法的独立性,将其独立抽离。真正可用于分片操作的是分片键 + 分片算法,也就是分片策略。目前提供5种分片策略。

标准分片策略

对应StandardShardingStrategy。提供对SQL语句中的=, >, <, >=, <=, IN和BETWEEN AND的分片操作支持。StandardShardingStrategy只支持单分片键,提供PreciseShardingAlgorithm和RangeShardingAlgorithm两个分片算法。PreciseShardingAlgorithm是必选的,用于处理=和IN的分片。RangeShardingAlgorithm是可选的,用于处理BETWEEN AND, >, <, >=, <=分片,如果不配置RangeShardingAlgorithm,SQL中的BETWEEN AND将按照全库路由处理。

复合分片策略

对应ComplexShardingStrategy。复合分片策略。提供对SQL语句中的=, >, <, >=, <=, IN和BETWEEN AND的分片操作支持。ComplexShardingStrategy支持多分片键,由于多分片键之间的关系复杂,因此并未进行过多的封装,而是直接将分片键值组合以及分片操作符透传至分片算法,完全由应用开发者实现,提供最大的灵活度。

行表达式分片策略

对应InlineShardingStrategy。使用Groovy的表达式,提供对SQL语句中的=和IN的分片操作支持,只支持单分片键。对于简单的分片算法,可以通过简单的配置使用,从而避免繁琐的Java代码开发,如: t_user_$->{u_id % 8} 表示t_user表根据u_id模8,而分成8张表,表名称为t_user_0到t_user_7。

Hint分片策略

对应HintShardingStrategy。通过Hint指定分片值而非从SQL中提取分片值的方式进行分片的策略。

不分片策略

对应NoneShardingStrategy。不分片的策略。


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:/java/47.html