ShardingSphere 分片算法

这篇具有很好参考价值的文章主要介绍了ShardingSphere 分片算法。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前言

测试ShardingSphere版本:5.2.0

下面配置中省略部分前缀,仅供参考

自动分片算法 Auto Sharding Alogorithm

自动分片算法通常用在 auto-tables 中,只需配置 actualDataSources 后,其他由分片算法自行解析处理。

注意,通常自动分片算法中的分片表都是在数据源中采用类似轮训的方式进行规律分片的,如:

    db_0.user_0, db_1.user_1, db_2.user_2, db_0.user_3, db_1.user_4, db_2.user_5, ...

也就是 db_{i}.user_{ni + n - 1},n为第几轮

取模 MOD

类似 MySQL的 PATITION 里的 MOD,由ShardingSphere通过分片数和取模的分母,自动计算实际表个数。

属性

名称

类型

描述

sharding-count

int

分片数

案例

该案例实际需要 8 个数据源(也支持单数据源的场景),并且每个数据源中各有 4 个user分表,并且分表格式为 user_${0..31}

        autoTables:
          user:
            logicTable:
            actualDataSources: ds_${0..7} # 数据源inline表达式,会自动识别算法:分片键 % 8 
            shardingStrategy: # 分片策略
              standard:
                shardingColumn: id
                shardingAlgorithmName: mod
shardingAlgorithms:
  mod:
    type: MOD
    props:
      sharding-count: 32 # 分片数

散列取模 HASH_MOD

MOD取模通常使用与数组类型的分片,而HASH_MOD不仅适用于数值也适用于字符串(通过hash值取模)列进行分片。该算法基本和MOD类似

属性

名称

类型

描述

sharding-count

int

分片数

案例

该案例只有一个数据源,但库内有 6个分表,并且按 order_id 的 hash值进行取模计算得到实际表。

        autoTables:
          t_order:
            actual-data-nodes: ds.t_order_$->{0..5}
            table-strategy:
              standard:
                sharding-algorithm-name: t-order-algorithm
                sharding-column: order_id
sharding-algorithms:
  t-order-algorithm:
    type: HASH_MOD
    props:
      sharding-count: '6'

容量范围 VOLUME_RANGE

该算法会根据 (${range-upper} - ${range-lower}) / ${sharding-volume} + 2 来算出实际的分片数量,从而实现自动分片功能。

属性

名称

类型

描述

range-lower

Long

范围下界

range-upper

Long

范围上界

sharding-volume

Long

每个分片容量

案例

  auto-tables:
    user:
      actualDataSources: db_${0..1}
      shardingStrategy:
        standard:
          shardingAlgorithmName: volume
          shardingColumn: id
sharding-algorithms:
  volume:
    type: VOLUME_RANGE
    props:
      range-lower: 0
      range-upper: 20000
      sharding-volume: 10000

要注意,这个算法之所以 + 2 ,实际上包含了两个隐藏表,用于储存小于 range-lower大于 range-upper 这两种情况的数据。

也就是说,上面的例子包含4((20000 - 0) / 10000 + 2)个分片

db_0: 
  - user0: (-∞..0) 
  - user2: [10000..20000) 
db_1:
  - user1: [0..10000) 
  - user3: [20000..+∞)

边界范围 BOUNDARY_RANGE

该算法会根据自定义范围进行分片,如0~100在分片0,100~1000在分片1,1000~1500在分片2等。

属性

名称

类型

描述

sharding-ranges

String

分片范围,多个边界可以用 , 隔开

案例

  auto-tables:
    user:
      actualDataSources: db_${0..1}
      shardingStrategy:
        standard:
          shardingAlgorithmName: boundary
          shardingColumn: id
sharding-algorithms:
  boundary:
    type: BOUNDARY_RANGE
    props:
      sharding-ranges: 10,15,100,12000,16000

在面例子中的范围字符串可以拆分为

-∞..10, 
10..15, 
15..100, 
100..12000, 
12000..16000, 
16000..+∞

实际上 BOUNDARY_RANGE 有点像 VOLUME_RANGE,但 BOUNDARY_RANGE 的更灵活容量长度可变

自动日期间隔 AUTO_INTERVAL

日期间隔将按 时间开始边界时间结束边界 之间的秒数除以 分片秒数 再加 2,从而计算出总分片数。也就是 ({datetime-upper} - {datetime-lower}) / sharding-seconds + 2

这里的加2也是用于补上小于 datetime-lower 大于 datetime-upper 的分片。

属性

名称

类型

描述

datetime-lower

String

分片时间开始边界,格式 yyyy-MM-dd HH:mm:ss

datetime-upper

String

分片时间结束边界,格式 yyyy-MM-dd HH:mm:ss

sharding-seconds

long

按多少秒一个分片进行分片

案例

  auto-tables:
    user:
      actualDataSources: db_${0..1}
      shardingStrategy:
        standard:
          shardingAlgorithmName: auto_interval
          shardingColumn: create_time
auto_interval:
  type: AUTO_INTERVAL
  props:
    datetime-lower: 2022-01-02 00:00:00
    datetime-upper: 2022-01-05 00:00:00
    sharding-seconds: 93600 # 一天

该案例中,会按解析为:

?, 2022-01-02 00:00:00 = 0
2022-01-02 00:00:00, 2022-01-03 00:00:00 = 1
...
2022-01-05 00:00:00, ? = 3

标准分片算法 Standard Sharding Algorithm

以下算法只适用于 standard 策略

行间分片算法 INLINE

行间分片通常用于SQL中单个 =IN 操作的分键字段

属性

名称

类型

描述

algorithm-expression

String

分片表达式

allow-range-query-with-inline-sharding(非必须)

boolean

是否允许范围查询。注意,范围查询时将会忽略分片策略,直接使用全路由

案例

  tables:
    position:
      actualDataNodes: db_${0..1}.position # 该表达式表示 db_0.position, db_1.position
      databaseStrategy:
        standard:
          shardingColumn: id
          shardingAlgorithmName: id-mod
sharding-algorithms:
  id-mod:
    type: INLINE
    props:
      algorithm-expression: db_${id % 2} # 该表达式表示 db_0 或 db_1

时间间隔分片 Interval Sharding Algorithm

该分片算法类似AUTO_INTERVAL,但比它要更加灵活,能够配置日期格式、分片后缀格式等,不过也因此配置更加复杂

属性

名称

类型

描述

默认值

datetime-pattern

String

自定义的日期格式,如:yyyy-MM-dd

datetime-lower

String

分片时间开始边界

datetime-upper(按需)

String

分片时间结束边界

Now

sharding-suffix-pattern

String

库表分片后缀格式(逻辑表_后缀),格式必须和 datetime-interval-unit 一致,如:yyyyMM对应MONTHS

datetime-interval-amount(按需)

int

分片间隔

1

datetime-interval-unit(按需)

String

分片间隔时间单位。可选址参考ChronoUnit类

DAYS

案例

  tables:
    position:
      actualDataNodes: db_${202201..202206}.position # 该表达式表示 db_202201.position, db_202202.position...
      databaseStrategy:
        standard:
          shardingColumn: create_time
          shardingAlgorithmName: month_interval
sharding-algorithms:
  type: INTERVAL
  props:
    datetime-pattern: yyyy-MM-dd HH:mm:ss
    datetime-lower: 2022-01-01 00:00:00
    datetime-interval-unit: MONTHS
    sharding-suffix-pattern: yyyyMM

复合分片算法 Complex Sharding Algorithm

以下算法只适用于 complex 策略

复合行间分片算法 COMPLEX_INLINE

可以使用 INLINE 进行多分片键分片。

属性

名称

类型

描述

sharding-columns(非必须)

String

分片键名称,通常在配置tables信息时指定

algorithm-expression

String

分片表达式

allow-range-query-with-inline-sharding(非必须)

boolean

是否允许范围查询。注意,范围查询时将会忽略分片策略,直接使用全路由

案例

  tables:
    position:
      actualDataNodes: db_${0..1}_${0..2}.position
      databaseStrategy:
        complex:
          shardingColumns: id, oid
          shardingAlgorithmName: uoid_complex
sharding-algorithms:
  uoid_complex:
    type: COMPLEX_INLINE
    props:
      algorithm-expression: db_${id % 2}_${oid % 3} # 该表达式表示 db_0_0 到 db_1_2

自定义 complex 分片算法 {Custome}

实现 ComplexKeysShardingAlgorithm 接口

/**
 * 基于 id 和 城市 的分片算法
 *
 * @author Jayin
 * @email 1035933250@qq.com
 * @date 2022/10/11
 */
public class IdCityTableShardingAlgorithm implements ComplexKeysShardingAlgorithm {
    private String tablePrefix;
    private int shardingCount;
    /** 配置值需要储存 */
    private Properties props;

    @Override
    public Collection<String> doSharding(Collection collection, ComplexKeysShardingValue complexKeysShardingValue) {
        // Map的值为 Collection 类型,获取对象时需要取第一个元素
        String city = (String) ((Collection) complexKeysShardingValue.getColumnNameAndShardingValuesMap().get("city")).toArray()[0];
        Long id = (Long) ((Collection) complexKeysShardingValue.getColumnNameAndShardingValuesMap().get("id")).toArray()[0];
        // 根据表前缀、所在地区和分片得到实际表
        String table = this.tablePrefix + "_" + city + "_" + (id % shardingCount);
        if (!collection.contains(table)) {
            return null;
        }
        return Collections.singleton(table);
    }

    /**
     * 返回配置值,因为后续对每个操作进行创建的算法对象都会获取 最初的配置信息,作为新创建对象的配置原型
     * @return
     */
    @Override
    public Properties getProps() {
        return props;
    }

    @Override
    public String getType() {
        return "ID_CITY";
    }

    /**
     * 算法初始化,该部分可按算法需要从 props 中获取参数
     * @param properties
     */
    @Override
    public void init(Properties properties) {
        this.props = properties;
        tablePrefix = StringUtils.defaultString(properties.getProperty("tablePrefix"), "position");
        shardingCount = Integer.parseInt(StringUtils.defaultString(properties.getProperty("shardingCount"), "3"));
    }
}

按 SPI 规范配置复合分片算法键类

resources/META-INF/services/org.apache.shardingsphere.sharding.spi.ShardingAlgorithm 文件中添加自定义主键类全类名

xyz.me4cxy.shardingjdbc.algorithm.IdCityTableShardingAlgorithm

使用复合分片算法

spring.shardingsphere.rules.sharding:
  tables:
    user:
      tableStrategy:
        actualDataNodes: db.user_shenzhen_${0..1}, db.user_guangzhou_${0..1} # 定义深圳、广州两个地区相关表
        complex: # 使用复合算法
          shardingColumns: id, city # 分片字段,也就是doSharding的数据 ComplexKeysShardingValue 来源,多个用 , 隔开
          shardingAlgorithmName: id-city # 采用自定义复合算法,id、城市分片
  sharding-algorithms:
    id-city: # 注册算法
      type: ID_CITY
      props: # 添加算法所需额外配置
        tablePrefix: user # 表前缀
        shardingCount: 2 # 表分片数

Hint分配算法 Hint Sharding Algorithm

以下算法适用于 hint 策略

hint行间分片算法 HINT_INLINE

该算法通过 ${value} 占位符,能够替换 HintManager 中添加值,如果添加多次值时,将会遍历每个字并执行一次 doSharding,适合用在按单个外部参数进行分片的情况。

属性

名称

类型

描述

默认值

algorithm-expression

String

分片表达式,通过 ${value} 注入实际值

${value}

案例

  tables:
    test:
      actualDataNodes: db_${0..1}.test
      databaseStrategy:
        hint:
          shardingAlgorithmName: sys-complex-hint
sharding-algorithms:
  sys-complex-hint:
    type: HINT_INLINE
    props:
      algorithm-expression: db_${value} // 将hint注入的值代入,如 db_1

--- 使用
@Test
public void testHint() {
    try (HintManager hintManager = HintManager.getInstance()) {
        hintManager.addDatabaseShardingValue("test", 1L); // 指定hint注入值
        System.out.println(testService.getById(3L));
    }
}

自定义 hint 分片算法

用于处理使用Hint行分片的场景。对于由非SQL字段来作为分片字段的场景,而是通过其他外部方式来进行分库分表时,可使用SQL Hint灵活注入分片字段。如:根据不同端展示不同数据,而“端”由应用控制。需要通过实现 HintShardingAlgorithm 接口完成分片。

详情参考:ShardingSphere 从源码查看hint为什么失效

基于自定义算法类分片算法 Class Based Sharding Algorithm

以下算法可适用于 standard、complex、hint

由于自定义算法通常需要注册到SPI中,但通过该算法能够配置自定义算法类,从而省去注册SPI的步骤

注意,该算法能够将自身的 props 透传给自定义算法类的实例,所以如果自定义算法需要配置参数可通过 props 进行配置

属性

名称

类型

描述

strategy

String

自定义的算法类使用哪种分片策略

algorithmClassName

String

分片算法的全类名文章来源地址https://www.toymoban.com/news/detail-407313.html

案例

  tables:
    position:
      actualDataNodes: db_${0..1}_${0..2}.position
      databaseStrategy:
        complex:
          shardingColumns: id, oid
          shardingAlgorithmName: uoid_complex
sharding-algorithms:
  id-city: 
    type: CLASS_BASED
    props: 
      strategy: complex
      algorithmClassName: xyz.me4cxy.shardingjdbc.algorithm.IdCityTableShardingAlgorithm
      # 自定义算法的配置
      tablePrefix: user # 表前缀
      shardingCount: 2 # 表分片数

到了这里,关于ShardingSphere 分片算法的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 0101读写分离测试-jdbc-shardingsphere-中间件

    shardingshpere-jdbc定位为轻量级 Java 框架, 在 Java 的 JDBC 层提供的额外服务 。 它使用客户端直连数据库, 以 jar 包形式提供服务 ,无需额外部署和依赖,可理解为增强版的 JDBC 驱动,完全兼容 JDBC 和各种 ORM 框架。 关于mysql配置主从复制,可以参考之前写的文章= 0101docker mysq

    2024年02月11日
    浏览(46)
  • 软件测试---前言篇

    上面这是官话 . 在我们日常生活中 , 就有许多测试的行为 , 比如地铁站的金属检测仪 , 用于检测旅客是否携带了违禁物品 ; 再比如测谎仪 , 通过记录人在情绪变化时的各种生理变化 , 判断是否说谎了 , 等等 . 企业研发出一个产品 , 能直接上线给用户或者进行销售吗 ? 显然这不

    2024年02月11日
    浏览(37)
  • 【算法与数据结构】--前言

    欢迎来到《算法与数据结构》专栏!这个专栏将引领您进入计算机科学领域中最重要、最精彩的领域之一:算法与数据结构。不管您是一名初学者,还是已经拥有一定编程经验的开发者,都可以从这里找到有益的知识和实践。 在计算机科学的世界里,算法和数据结构是至关重

    2024年02月07日
    浏览(245)
  • 【优选算法专栏】专题十六:BFS解决最短路问题---前言

    本专栏内容为:算法学习专栏,分为优选算法专栏,贪心算法专栏,动态规划专栏以及递归,搜索与回溯算法专栏四部分。 通过本专栏的深入学习,你可以了解并掌握算法。 💓博主csdn个人主页:小小unicorn ⏩专栏分类:算法从入门到精通 🚚代码仓库:小小unicorn的代码仓库

    2024年04月15日
    浏览(51)
  • Sharding-JDBC之PreciseShardingAlgorithm(精确分片算法)

      在我之前的文章里,数据的分库分表都是基于行表达式的方式来实现的,看起来也蛮好用,也挺简单的,但是有时会有些复杂的规则,可能使用行表达式策略会很复杂或者实现不了,我们就讲另外一种分片策略,精确分片算法,通常用来处理=或者in条件的情况比较多。

    2024年02月11日
    浏览(45)
  • Sharding-JDBC分库分表四种分片算法

    精确分片算法(PreciseShardingAlgorithm)精确分片算法(=与IN语句),用于处理使用单一键作为分片键的=与IN进行分片的场景。需要配合StandardShardingStrategy使用 范围分片算法(RangeShardingAlgorithm)用于处理使用单一键作为分片键的BETWEEN AND进行分片的场景。需要配合StandardShardingS

    2024年02月10日
    浏览(40)
  • Sharding-JDBC 自定义一致性哈希算法 + 虚拟节点 实现数据库分片策略

    分片操作是分片键 + 分片算法,也就是分片策略。目前Sharding-JDBC 支持多种分片策略: 标准分片策略 对应StandardShardingStrategy。提供对SQL语句中的=, IN和BETWEEN AND的分片操作支持。 复合分片策略 对应ComplexShardingStrategy。复合分片策略。提供对SQL语句中的=, IN和BETWEEN AND的分片操作

    2024年02月02日
    浏览(60)
  • 【ShardingSphere】ShardingSphere 官网资源链接

    https://shardingsphere.apache.org 中文文档 https://shardingsphere.apache.org/document/current/cn/overview/ DistSQL DistSQL(Distributed SQL) 是 Apache ShardingSphere 特有的操作语言。 它与标准 SQL 的使用方式完全一致,用于提供增量功能的 SQL 级别操作能力。 https://shardingsphere.apache.org/document/current/cn/user-m

    2024年02月09日
    浏览(45)
  • Java微服务系列之 ShardingSphere - ShardingSphere-JDBC

    🌹作者主页:青花锁 🌹简介:Java领域优质创作者🏆、Java微服务架构公号作者😄 🌹简历模板、学习资料、面试题库、技术互助 🌹文末获取联系方式 📝 [Java项目实战] 介绍Java组件安装、使用;手写框架等 [Aws服务器实战] Aws Linux服务器上操作nginx、git、JDK、Vue等 [Java微服务

    2024年02月02日
    浏览(43)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包