ShardingJDBC分片策略

概述

ShardingJDBC 提供了多种分片策略,以适应不同的应用场景。这些策略通过将数据分布到多个数据库实例或表中,提高系统的性能和可扩展性。分片策略的选择对系统的查询性能、数据均衡性以及扩展性有重要影响。常见的分片策略包括范围分片、哈希分片、列值分片、连续分片、复合分片、广播表分片和异构分片。

分片策略详解

自动分片算法

这种算法会根据相应配置以及选择的不同算法,自动进行分片

  • 取模分片算法(MOD):取模分片算法通过对分片键进行取模运算来决定分片位置,适用于数据量大且均匀分布的场景

    1
    2
    3
    4
    5
    6
    7
    8
    sharding-algorithms:
    # 分片算法名
    my_mod_algorithms:
    #类型
    type: MOD
    # 算法配置
    props:
    sharding-count: 2
  • 哈希取模分片算法(HASH_MOD):哈希取模分片算法通过对分片键进行哈希运算后再取模来决定分片位置,进一步均匀数据分布。

    1
    2
    3
    4
    5
    6
    7
    8
    sharding-algorithms:
    # 分片算法名
    my_hashmod_algorithms:
    #类型
    type: HASH_MOD
    # 算法配置
    props:
    sharding-count: 2
  • 基于分片容量的范围分片算法(VOLUME_RANGE):基于分片容量的范围分片算法通过预定义每个分片的容量来决定数据的分布

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    sharding-algorithms:
    # 分片算法名
    my_volrange_algorithms:
    #类型
    type: VOLUME_RANGE
    # 算法配置
    props:
    # 分片容量
    sharding-volume: 10
    # 数据下界
    range-lower: 1
    # 数据上界
    range-upper: 40
  • 基于分片边界的范围分片算法(BOUNDARY_RANGE):基于分片边界的范围分片算法通过预定义的分片边界来决定数据的分布,适用于有明显边界的数据

    1
    2
    3
    4
    5
    6
    7
    8
    9
    sharding-algorithms:
    # 分片算法名
    my_bdrange_algorithms:
    #类型
    type: BOUNDARY_RANGE
    # 算法配置
    props:
    # 分片的范围边界
    sharding-ranges: 20,40
  • 自动时间段分片算法(AUTO_INTERVAL):自动时间段分片算法根据时间范围自动创建分片,适用于时间序列数据

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    sharding-algorithms:
    # 分片算法名
    my_autointerval_algorithms:
    #类型
    type: AUTO_INTERVAL
    # 算法配置
    props:
    # 起始时间
    datetime-lower: 2024-05-19 00:00:00
    # 结束时间
    datetime-upper: 2024-12-30 23:59:59
    # 单一分片所能承载的最大时间即分片大小(案例是一天)
    sharding-seconds: 86400

    标准分片算法

标准分片算法基于自定义的分片规则决定数据的分布,适用于多种复杂场景。

  • 行表达式分片算法(INLINE):提供了简单的单分片键的,基于goovy 表达式的inline 配置语句

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    sharding-algorithms:
    # 分片算法名
    my_inline_algorithms:
    #类型
    type: INLINE
    # 算法配置
    props:
    # 分片算法的行表达式
    algorithm-expression: t_order_$->{user_id % 2}
    # 是否允许范围查询。
    allow-range-query-with-inline-sharding: true
  • 时间范围分片算法(INTERVAL): 一种时间范围的分片,跟自动时间段不同的是,分片的后缀是可以有意义的

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    sharding-algorithms:
    # 分片算法名
    my_interval_algorithms:
    #类型
    type: INTERVAL
    # 算法配置
    props:
    # 分片键的时间戳格式
    datetime-pattern: yyyy-MM-dd HH:mm:ss
    # 下界
    datetime-lower: 2024-01-01 00:00:00
    # 上界
    datetime-upper: 2025-01-01 00:00:00
    # 分片数据源或真实表的后缀格式
    sharding-suffix-pattern: yyyy_MM
    # 分片键时间间隔
    datetime-interval-amount: 1
    # 分片键时间间隔单位
    datetime-interval-unit: MONTHS

    复合分片算法

复合分片算法结合多种分片算法,适用于需要综合考虑多种因素的复杂场景。

  • 复合行表达式分片算法(COMPLEX_INLINE):支持多个分片键并且使用行表达式来分片

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    sharding-algorithms:
    # 分片算法名
    my_interval_algorithms:
    #类型
    type: COMPLEX_INLINE
    # 算法配置
    props:
    # 复合的分片键
    sharding-columns: user_id,order_id
    # 具体的分片算法
    algorithm-expression: t_order_$->{(order_id % 2) + (user_id % 2)}
    # 是否允许范围查询
    allow-range-query-with-inline-sharding: true

    Hint 分片算法

Hint分片算法通过手动指定分片,适用于无法通过分片键计算分片的特殊场景。

  • Hint 行表达式分片算法(HINT_INLINE):通过inline 表达式和 Api 来实现一个分片算法

    算法配置:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    sharding-algorithms:
    # 分片算法名
    my_interval_algorithms:
    #类型
    type: HINT_INLINE
    # 算法配置
    props:
    # 具体的分片算法
    algorithm-expression: algorithm-expression: t_order_$->{value % 2}

    程序中传入:

    1
    2
    3
    hintManager.addTableShardingValue("t_order",i);
    //执行完毕需要清空
    hintManager.clearShardingValues();

    总结

每种分片策略都有其适用场景和局限性。选择合适的分片策略需要综合考虑数据量、查询类型、业务需求等多方面因素。以下是不同分片策略的优缺点总结:

分片策略 优点 缺点
取模分片算法 实现简单,数据分布均匀 不支持范围查询
哈希取模分片算法 数据分布更加均匀,适用于大规模数据场景 范围查询性能差
基于分片容量的范围分片算法 支持范围查询,数据分布可控 需要预估分片容量
基于分片边界的范围分片算法 支持范围查询,数据分布明确 需要准确定义分片边界
自动时间段分片算法 支持范围查询,自动分片管理 数据分布随时间变化
标准分片算法 灵活性高,适用于多种业务需求 实现复杂
复合分片算法 灵活性高,满足复杂业务需求 实现复杂,维护成本高
Hint分片算法 精确控制分片,适用于特殊场景 实现复杂,增加应用层逻辑复杂性

在实际应用中,选择合适的分片策略应结合具体业务需求和技术环境,进行详细分析和测试,以达到最佳的性能和稳定性。

如果官方提供的分片算法仍然无法满足需求,官方还可以提供了自定义类实现自定义分片算法的功能:

  1. 实现不同的接口:

    • 标准分片:StandardShardingAlgorithm
    • 复合分片:ComplexKeysShardingAlgorithm
    • Hint分片:HintShardingAlgorithm
  2. 重新doSharding方法

  3. 进行配置:

    1
    2
    3
    4
    5
    6
    sharding-algorithms:
    table-inline:
    type: CLASS_BASED
    props:
    strategy: COMPLEX
    algorithmClassName: com.wht.demo.shardingalgorithm.myComplexAlgorithm