ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

sharding-jdbc 分片策略(行分片策略踩坑笔记)

2021-07-21 13:02:29  阅读:511  来源: 互联网

标签:jdbc 策略 each shardingValue 分片 sharding id


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

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

Error querying database. Cause: java.lang.IllegalStateException: Inline strategy cannot support range sharding.

原因:使用行分片策略
原先的sharding-jdbc的分片策略配置是:

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

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

解决方案:使用标准分片策略
对应配置:

sharding:
  binding-tables: tableName
  tables:
    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里的实现类:

public final class PreciseModuloAlgorithm implements PreciseShardingAlgorithm<Integer> {

    @Override
    public String doSharding(final Collection<String> availableTargetNames, final PreciseShardingValue<Integer> shardingValue) {
        for (String each : availableTargetNames) {
            if (each.endsWith(shardingValue.getValue() % 10 + "")) {
                return each;
            }
        }
        throw new UnsupportedOperationException();
    }
}

public final class RangeModuloAlgorithm implements RangeShardingAlgorithm<Integer> {
    
    @Override
    public Collection<String> doSharding(final Collection<String> availableTargetNames, final RangeShardingValue<Integer> shardingValue) {
        Collection<String> result = new LinkedHashSet<>(availableTargetNames.size());
        int minValue = shardingValue.getValueRange().hasLowerBound() ? shardingValue.getValueRange().lowerEndpoint() : Integer.MIN_VALUE;
        int maxValue = shardingValue.getValueRange().hasUpperBound() ? shardingValue.getValueRange().upperEndpoint() : Integer.MAX_VALUE;
        // 最大值减最小值,得到差
        long range = BigInteger.valueOf(maxValue).subtract(BigInteger.valueOf(minValue)).longValue();
        // 最小值得绝对值除10的余数
        int begin = Math.abs(minValue) % 10;
        // 超过9直接返回可用的表名,这里的9是,自己的分片策略值
        // 假设我的分片策略是:对id除以10,取余数
        if (range > 9) {
            return availableTargetNames;
        }
        // 如果差在分片策略内的,就直接取余数,得到对应的表名
        for (int i = begin; i <= range; i += 1) {
            for (String each : availableTargetNames) {
                if (each.endsWith(i + "")) {
                    result.add(each);
                }
            }
        }
        return result;
    }
}
  • sharding-jdbc 分片策略

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

  1. 标准分片策略

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

  1. 复合分片策略

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

  1. 行表达式分片策略

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

  1. Hint分片策略

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

  1. 不分片策略

对应NoneShardingStrategy。不分片的策略。

标签:jdbc,策略,each,shardingValue,分片,sharding,id
来源: https://blog.csdn.net/hualinger/article/details/118963708

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有