Sharding-standard策略(四)
创始人
2024-05-29 03:13:01
0

简介

参考代码工程(2-standard)

第三节使用springboot搭建sharding环境时候以最简单的inline策略为演示,发现inline只支持最简单的等于查询。对于范围查询不支持(表通常要结合时间最范围查询)

此时要引用标准分片策略(standard)

standard策略可以看到配置信息一共3个参数

#分片主键
sharding-column= 
# 精准分片算法-》指定我们实现类
precise-algorithm-class-name= 
# 范围查询算法-》指定我们实现类
range-algorithm-class-name= 

配置信息

使用yaml修改配置类成以下

#  单库分表 配置
spring:shardingsphere:datasource:# 配置数据库名称 相当于给数据源取别名(可以配置多个库,以逗号隔开)names: m1# 配置具体数据库连接信息m1:type: com.alibaba.druid.pool.DruidDataSourcedriverClassName: com.mysql.cj.jdbc.Driver# 配置 数据库 testurl: jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=UTCusername: rootpassword: root# 分片策略sharding:# 配置不同表的 分片策略tables:# 配置 具体的 逻辑表的 分片策略t_order:# t_order 订单表的 主键规则keyGenerator:# 主键列column: order_id# 主键生成规则 (SNOWFLAKE 雪花算法 生成分布式唯一ID)type: SNOWFLAKE# 未知作用#            props:#              worker:#                id: 1# 配置 t_order 订单表的 具体数据库物理表的映射关系 表达式actualDataNodes: m1.t_order_$->{1..2}# 表策略tableStrategy:standard:# 分片列sharding-column: order_id# 范围分片算法类名称,用于 范围查询 可选。该类需实现 RangeShardingAlgorithm 接口并提供无参数的构造器range-algorithm-class-name: com.wnn.sd.algorithm.MyRangeShardingAlgorithm# 精确分片算法类名称,用于 = 和 IN。该类需实现 PreciseShardingAlgorithm 接口并提供无参数的构造器precise-algorithm-class-name: com.wnn.sd.algorithm.MyPreciseShardingAlgorithm# 配置是否打印SQLprops:sql.show: true

精准分片算法(一)

创建一个包“com.wnn.sd.algorithm”,首先实现精准分片算法PreciseShardingAlgorithm,所谓精准分片算法,可以参考inline算法一样实现一个对订单表主键取摸2的算法

package com.wnn.sd.algorithm;import java.math.BigInteger;
import java.util.Collection;import org.apache.shardingsphere.api.sharding.standard.PreciseShardingAlgorithm;
import org.apache.shardingsphere.api.sharding.standard.PreciseShardingValue;import lombok.extern.slf4j.Slf4j;/*** @Description: 精确匹配查询,需要实现PreciseShardingAlgorithm,可以实现对 `=`以及`in`的查询**/
@Slf4j
public class MyPreciseShardingAlgorithm implements PreciseShardingAlgorithm {/*** 精确匹配查询** @param tbNames*            数据库中所有的事实表* @param shardingValue*            分片相关信息* @return 返回匹配的数据源*/@Overridepublic String doSharding(Collection tbNames, PreciseShardingValue shardingValue) {// 获取-打印逻辑表String logicTableName = shardingValue.getLogicTableName();log.info("logicTableName = {}", logicTableName);// 主键值转换BigInteger做计算BigInteger orderId = BigInteger.valueOf(shardingValue.getValue());// 取摸算法%2+1BigInteger tabelNuber = (orderId.mod(new BigInteger("2"))).add(new BigInteger("1"));// 打印实际路由后的表String actTableName = logicTableName + "_" + tabelNuber;log.info("actTableName= {}", actTableName);// 判断算法的结果是否在数据库实际表列表中if (tbNames.contains(logicTableName + "_" + tabelNuber)) {return actTableName;}throw new RuntimeException("表不存在");}
}

把t_order_1和t_order_2清除,使用Test类的add()方法(参考上一节Test类)给数据库添加10条数据,结果保持和inline一致。

    /*** 添加数据*/@Testpublic void addOrder() {for (int i = 0; i < 10; i++) {Order order = new Order();order.setOrderName("wn" + i);orderMapper.insert(order);}}/*** 等于查询 ID基于表2*/@Testpublic void queryByEQ() {List orders =orderMapper.selectList(new LambdaQueryWrapper().eq(Order::getOrderId, 1629805480188895233L));orders.forEach(o -> System.out.println(o));}

可以看到插入日志中输出了@Slf4j 下 log.info()信息,说明新数据,sharding能够根据我们的配置信息,加载我们实现的算法类

add()

2023-03-05 15:06:52.819  INFO 23220 --- [           main] c.w.s.a.MyPreciseShardingAlgorithm       : logicTableName = t_order
2023-03-05 15:06:52.819  INFO 23220 --- [           main] c.w.s.a.MyPreciseShardingAlgorithm       : actTableName= t_order_2

queryByEQ() ,路由查询结果正确

2023-03-05 15:09:47.354  INFO 35236 --- [           main] c.w.s.a.MyPreciseShardingAlgorithm       : logicTableName = t_order
2023-03-05 15:09:47.355  INFO 35236 --- [           main] c.w.s.a.MyPreciseShardingAlgorithm       : actTableName= t_order_2
2023-03-05 15:09:47.374  INFO 35236 --- [           main] ShardingSphere-SQL                       : Logic SQL: SELECT  order_id,2023-03-05 15:09:47.375  INFO 35236 --- [           main] ShardingSphere-SQL                       : Actual SQL: m1 ::: SELECT  order_id,order_name,order_type,order_desc,create_user_id,create_user_name,create_time  FROM t_order_2 WHERE (order_id = ?) ::: [1629805480188895233]

范围分片算法(二)

再实现范围查询算法MyRangeShardingAlgorithm类,该类实现RangeShardingAlgorithm类,此时从方法shardingValue中拿到SQL语句中between的上限和下限值,因为没有具体业务分片算法暂时列为//TODO,返回结果为全表(一共2张表)测试通过RangeShardingAlgorithm实现类doSharding()方法是否能够执行between查询

package com.wnn.sd.algorithm;import java.util.Arrays;
import java.util.Collection;import org.apache.shardingsphere.api.sharding.standard.RangeShardingAlgorithm;
import org.apache.shardingsphere.api.sharding.standard.RangeShardingValue;import lombok.extern.slf4j.Slf4j;/*** 实现范围查询逻辑**/
@Slf4j
public class MyRangeShardingAlgorithm implements RangeShardingAlgorithm {@Overridepublic Collection doSharding(Collection availableTargetNames,RangeShardingValue shardingValue) {Long upperValue = shardingValue.getValueRange().upperEndpoint();// 上限Long lowerValue = shardingValue.getValueRange().lowerEndpoint();// 下限//TODOString logicTableName = shardingValue.getLogicTableName();log.info("MyRangeShardingAlgorithm +  logicTableName {}", logicTableName);return Arrays.asList(logicTableName + "_1", logicTableName + "_2");}
}

可以看到打印输出结果,不像使用inline那样报错,而是通过MyRangeShardingAlgorithm算法返回的表名执行SQL

2023-03-05 15:25:48.009  WARN 12852 --- [           main] c.b.m.c.t.support.ReflectLambdaMeta      : Unable to make field private final java.lang.Class java.lang.invoke.SerializedLambda.capturingClass accessible: module java.base does not "opens java.lang.invoke" to unnamed module @3d012ddd
2023-03-05 15:25:48.387  INFO 12852 --- [           main] c.w.s.a.MyRangeShardingAlgorithm         : MyRangeShardingAlgorithm +  logicTableName t_order2023-03-05 15:25:48.418  INFO 12852 --- [           main] ShardingSphere-SQL                       : Actual SQL: m1 ::: SELECT  order_id,order_name,order_type,order_desc,create_user_id,create_user_name,create_time  FROM t_order_1 WHERE (order_id BETWEEN ? AND ?) ::: [1629805480188895233, 1629805480214061057]
2023-03-05 15:25:48.418  INFO 12852 --- [           main] ShardingSphere-SQL                       : Actual SQL: m1 ::: SELECT  order_id,order_name,order_type,order_desc,create_user_id,create_user_name,create_time  FROM t_order_2 WHERE (order_id BETWEEN ? AND ?) ::: [1629805480188895233, 1629805480214061057]

结论

由此可见standard标准分片算法,实现相比inline繁杂一点。一般使用standard策略是为了搭配范围分片算法使用。

相关内容

热门资讯

【NI Multisim 14...   目录 序言 一、工具栏 🍊1.“标准”工具栏 🍊 2.视图工具...
银河麒麟V10SP1高级服务器... 银河麒麟高级服务器操作系统简介: 银河麒麟高级服务器操作系统V10是针对企业级关键业务...
不能访问光猫的的管理页面 光猫是现代家庭宽带网络的重要组成部分,它可以提供高速稳定的网络连接。但是,有时候我们会遇到不能访问光...
AWSECS:访问外部网络时出... 如果您在AWS ECS中部署了应用程序,并且该应用程序需要访问外部网络,但是无法正常访问,可能是因为...
Android|无法访问或保存... 这个问题可能是由于权限设置不正确导致的。您需要在应用程序清单文件中添加以下代码来请求适当的权限:此外...
北信源内网安全管理卸载 北信源内网安全管理是一款网络安全管理软件,主要用于保护内网安全。在日常使用过程中,卸载该软件是一种常...
AWSElasticBeans... 在Dockerfile中手动配置nginx反向代理。例如,在Dockerfile中添加以下代码:FR...
AsusVivobook无法开... 首先,我们可以尝试重置BIOS(Basic Input/Output System)来解决这个问题。...
ASM贪吃蛇游戏-解决错误的问... 要解决ASM贪吃蛇游戏中的错误问题,你可以按照以下步骤进行:首先,确定错误的具体表现和问题所在。在贪...
月入8000+的steam搬砖... 大家好,我是阿阳 今天要给大家介绍的是 steam 游戏搬砖项目,目前...