ShardingJdbc简述 & 分布式主键的方式

官方文档: https://shardingsphere.apache.org/document/current/cn/features/sharding/

配置

 <dependency>
     <groupId>org.apache.shardingsphere</groupId>
     <artifactId>sharding-jdbc-spring-boot-starter</artifactId>
     <version>4.0.0-RC1</version>
     <version>4.0.1</version>
 </dependency>
 <!-- for spring namespace -->
 <dependency>
     <groupId>org.apache.shardingsphere</groupId>
     <artifactId>sharding-jdbc-spring-namespace</artifactId>
     <version>4.0.0-RC1</version>
     <version>4.0.1</version>
 </dependency>
下面示例是单数据源配置,可以配置多个数据源做主从、分库分表 (可混合使用)。
​spring.shardingsphere:
    enabled: true
    props.sql.show: true
    datasource:
        names: ds0
        ds0:
            type: com.zaxxer.hikari.HikariDataSource
            driver-class-name: com.mysql.cj.jdbc.Driver
            jdbc-url: jdbc:mysql://${noob.dburl}?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&failOverReadOnly=false
            username: ${noob.dbuser}
            password: ${noob.dbpwd}
            data-source-properties: #下面子属性只能为小驼峰格式,同使用数据源中的配置属性
              maximumPoolSize: ${datasource.maximumPoolSize}
              minimumIdle: ${datasource.minimumIdle}
              maxLifetime: 300000
              connectionTimeout: 30000
              idleTimeout: 30000
              connectionTestQuery: SELECT 1
    sharding.tables:
        limit_use:
            actual-data-nodes: ds0.limit_use_0$->{0..9},ds0.limit_use_$->{10..31}
            table-strategy.complex.sharding-columns: loan_no,contract_no
            table-strategy.complex.algorithm-class-name: cn.noob.algorithm.sharding.MurmurConsistentHashFeatureCodeComplexShardingAlgorithm #扩展ComplexKeysShardingAlgorithm混合分片算法
        loan:
            actual-data-nodes: ds0.loan_0$->{0..9},ds0.loan_$->{10..31}
            table-strategy.standard.sharding-column: loan_no
            table-strategy.standard.precise-algorithm-class-name: cn.noob.algorithm.sharding.MurmurConsistentHashFeatureCodeShardingAlgorithm #扩展PreciseShardingAlgorithm标准精确分片算法
    sharding.bindingTables[0]: limit_use, repayment_plan #綁定表

绑定表

避免多表关联场景产生笛卡尔积结果。

sharding.bindingTables[0]: limit_use, repayment_plan
或者
sharding.bindingTables: 
     - limit_use, repayment_plan, loan, settle_detail
     - customer, bank_account

广播表

 所有的分片数据源中都存在的表结构及其数据均完全一致的表, 用于数据量不大且需要与海量数据的表进行关联查询的场景,例如:字典表。

spring.shardingsphere.sharding.broadcast-tables = t_dict

分页解决方式

通常sql语句需要按分表字段过滤,分页不能像常规那样指定分页数查询

  1. 翻页越往后导致limit 的offset 越来越大,查询效率下降。所以对于后翻太多页的操作直接拒绝(操作意义无效拒绝服务),或许更应该区分冷热数据,历史数据使用其他介质存储: eg. es、hive
  2. 按降序展示列表:
    1. “下一页” next:取每页数据最后一条记录的ID - lastId(当前页最小Id,首次查询不用传),取小于它的降序数据集的前 limit 条;
    2. “上一页” pre:  取每页数据第一条记录的ID - firstId(当前页最大Id),   取大于它的升序数据集的前 limit 条,随后在程序里再对结果集降序排列(Collections.reverse(list);), 以此来保证页面列表数据展示的顺序一致。
<select id="getByPage" resultMap="Contract">
		SELECT  * FROM contract
        <where>
            <if test="id != null and id != 0 ">
             <choose>
                 <when  test ="opType != null and opType == 'pre' ">
                      id >  #{id}
                 </when>
                    <otherwise>  id &lt; #{id}</otherwise>
             </choose>
            </if>
            <include refid="dynamicWhere" />
        </where>
        order by id
        <choose>
            <when  test ="opType != null and opType == 'pre' ">
                   asc
            </when>
            <otherwise>  desc </otherwise>
        </choose>
        limit #{pageSize}
	</select>

特性

SQL :: ShardingSphere

  1. 支持跨库关联查询,由 Federation 执行引擎提供支持。基于 XA 协议的两阶段事务和基于最终一致性的柔性事务支持
  2. 有限支持子查询, 子查询一定要有分表键!无论嵌套多少层,ShardingSphere都可以解析至第一个包含数据表的子查询,一旦在下层嵌套中再次找到包含数据表的子查询将直接抛出解析异常。通过子查询进行非功能需求,在大部分情况下是可以支持的,比如分页、统计总数等;而通过子查询实现业务查询当前并不能支持
  3. 只能通过sql字面提取用于分片的值,因此当分片键处于运算表达式或函数中时,ShardingSphere无法提前获取分片键位于数据库中的值,从而无法计算出真正的分片值。当出现此类分片键处于运算表达式或函数中的sql时,ShardingSphere将采用全路由的形式获取结果。
  4.  不能更新分表字段

路由

SELECT i.* FROM t_order o JOIN t_order_item i ON o.order_id=i.order_id WHERE o.order_id in (10, 11);

标准路由 

绑定关系表指路由使用相同分片规则的主表和子表。绑定表之间的多表关联查询不会出现笛卡尔积关联,关联查询效率将大大提升。此时走的是标准路由。

在不配置绑定表关系时,假设分片键order_id将数值10路由至第0片,将数值11路由至第1片,那么路由后的SQL应该为4条,它们呈现为笛卡尔积:

SELECT i.* FROM t_order_0 o JOIN t_order_item_0 i ON o.order_id=i.order_id WHERE o.order_id in (10, 11);
SELECT i.* FROM t_order_0 o JOIN t_order_item_1 i ON o.order_id=i.order_id WHERE o.order_id in (10, 11);
SELECT i.* FROM t_order_1 o JOIN t_order_item_0 i ON o.order_id=i.order_id WHERE o.order_id in (10, 11);
SELECT i.* FROM t_order_1 o JOIN t_order_item_1 i ON o.order_id=i.order_id WHERE o.order_id in (10, 11);

显式申明配置绑定表关系后,路由的sql应该为2条:

SELECT i.* FROM t_order_0 o JOIN t_order_item_0 i ON o.order_id=i.order_id WHERE o.order_id in (10, 11);
SELECT i.* FROM t_order_1 o JOIN t_order_item_1 i ON o.order_id=i.order_id WHERE o.order_id in (10, 11);

其中t_order在FROM的最左侧,ShardingSphere将会以它作为整个绑定表的主表。 所有路由计算将会只使用主表的策略,那么t_order_item表的分片计算将会使用t_order的条件。故绑定表之间的分区键最好是要相同。

笛卡尔路由

笛卡尔路由是最复杂的情况,它无法根据绑定表的关系定位分片规则,因此非绑定表之间的关联查询需要拆解为笛卡尔积组合执行。 如果上个示例中的SQL并未配置绑定表关系,那么路由的结果应为:

SELECT * FROM t_order_0 o JOIN t_order_item_0 i ON o.order_id=i.order_id  WHERE order_id IN (1, 2);
SELECT * FROM t_order_0 o JOIN t_order_item_1 i ON o.order_id=i.order_id  WHERE order_id IN (1, 2);
SELECT * FROM t_order_1 o JOIN t_order_item_0 i ON o.order_id=i.order_id  WHERE order_id IN (1, 2);
SELECT * FROM t_order_1 o JOIN t_order_item_1 i ON o.order_id=i.order_id  WHERE order_id IN (1, 2);

笛卡尔路由查询性能较低,需谨慎使用。

分布式主键

(75条消息) 分布式全局唯一主键_noob_can的博客-CSDN博客icon-default.png?t=N5K3https://blog.csdn.net/noob_can/article/details/131548271

 支持的分片策略

package org.apache.shardingsphere.core.strategy.route;

@NoArgsConstructor(access = AccessLevel.PRIVATE)
public final class ShardingStrategyFactory {
    
    /**
     * @param shardingStrategyConfig sharding strategy configuration
     * @return sharding strategy instance
     */
    public static ShardingStrategy newInstance(final ShardingStrategyConfiguration shardingStrategyConfig) {
        if (shardingStrategyConfig instanceof StandardShardingStrategyConfiguration) {
            return new StandardShardingStrategy((StandardShardingStrategyConfiguration) shardingStrategyConfig);
        }
        if (shardingStrategyConfig instanceof InlineShardingStrategyConfiguration) {
            return new InlineShardingStrategy((InlineShardingStrategyConfiguration) shardingStrategyConfig);
        }
        if (shardingStrategyConfig instanceof ComplexShardingStrategyConfiguration) {
            return new ComplexShardingStrategy((ComplexShardingStrategyConfiguration) shardingStrategyConfig);
        }
        if (shardingStrategyConfig instanceof HintShardingStrategyConfiguration) {
            return new HintShardingStrategy((HintShardingStrategyConfiguration) shardingStrategyConfig);
        }
        return new NoneShardingStrategy();
    }
}
  1. 标准分片StandardShardingStrategy:单一分片键。 精准分片PreciseShardingAlgorithm和范围分片RangeShardingAlgorithm

  2. 复合分片ComplexShardingStrategy:多个分片键关联逻辑处理ComplexKeysShardingAlgorithm
  3. Hint分片HintShardingStrategy:指定要查询的分库及分表HintShardingAlgorithm 。配置好使用hint策略的分表及分库算法后,HintManager里设置databaseSharding和tableSharding,使用 ThreadLocal 管理分片键值,仅在当前线程内生效。(还可以通过 SQL 中的特殊注释的方式引用 Hint, 指定了强制分片路由的 SQL 将会无视原有的分片逻辑,直接路由至指定的真实数据节点。)
  4. 行表达式分片InlineShardingStrategy :  在配置中使用 Groovy 表达式,提供对 SQL语句中的 = 和 IN 的分片操作支持,它只支持单分片键的精准规则
  5. 无实际的分片策略NoneShardingStrategy
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值