ShardingSphere-JDBC分片路由引擎

本文详细介绍了ShardingSphere-JDBC的分片路由引擎,包括路由装饰器、分片路由装饰器的实现,如MasterSlaveRouteDecorator和ShardingRouteDecorator。核心参数如RouteContext和ShardingRule在路由过程中的作用,以及不同类型的路由引擎,如ShardingDatabaseBroadcastRoutingEngine和ShardingStandardRoutingEngine的工作原理。此外,还讨论了读写分离路由装饰器的配置和实现。
摘要由CSDN通过智能技术生成

前言

上文ShardingSphere-JDBC分片解析引擎中介绍了分片流程中的解析引擎,重点介绍了解析引擎的核心组件ANTLR;本文继续介绍分片流程中的路由引擎,路由引擎可以说是整个分片流程的核心模块,用户自定义的分片算法都在路由引擎中执行;

开启日志

为了更加清晰详细的查看路由日志,开启SQL_SHOW功能:

  • 引入log4j相关jar,以及log4j.xml配置文件

  • 配置SQL_SHOW属性为开启:

    Properties prop = new Properties();
    prop.put(ConfigurationPropertyKey.SQL_SHOW.getKey(), true);
    

路由装饰器

路由引擎的外层包装了一层路由装饰器RouteDecorator,为什么要这么设计是因为除了我们正常走路由算法的路由引擎,ShardingSphere-JDBC还提供了读写分离功能,这其实在一定程度上来讲也是路由,而且这两种路由方式是可以叠加的;所有这里提供了一层抽象,实现类包括:

  • MasterSlaveRouteDecorator:读写分离路由装饰器;
  • ShardingRouteDecorator:分片路由装饰器,内部包含了各种路由引擎;

装饰器可以叠加,所以提供了优先级功能OrderAware,同时每个装饰器都有对应的规则,大致如下所示:

装饰器-RouteDecorator 配置-Configuration 规则-BaseRule 优先级-Order
MasterSlaveRouteDecorator MasterSlaveRuleConfiguration MasterSlaveRule 10
ShardingRouteDecorator ShardingRuleConfiguration ShardingRule 0

根据优先级可以知道首先执行ShardingRouteDecorator,有了路由结果再执行MasterSlaveRouteDecorator;部分启动类代码在DataNodeRouter中如下所示:

private final Map<BaseRule, RouteDecorator> decorators = new LinkedHashMap<>();
private RouteContext executeRoute(final String sql, final List<Object> parameters, final boolean useCache) {
   
      RouteContext result = createRouteContext(sql, parameters, useCache);
      for (Entry<BaseRule, RouteDecorator> entry : decorators.entrySet()) {
   
          result = entry.getValue().decorate(result, metaData, entry.getKey(), properties);
      }
      return result;
}

decorators会根据用户的配置来决定是否会启动对应的装饰器,可以参考上面的表格;下面按照优先级分别介绍两种装饰器;

分片路由装饰器

经过解析引擎获取到了SQLStatement,想要做分片路由除了此参数还需要另外一个重要参数分片路由规则ShardingRule ;有了这两个核心参数分片路由大致可以分为以下几步:

  • 获取分片条件ShardingConditions
  • 获取具体分片引擎ShardingRouteEngine
  • 执行路由处理,获取路由结果

在详细介绍每一步之前,首先介绍以下几个核心参数RouteContextShardingRule

核心参数

重点看一下RouteContextShardingRule这两个核心参数;

RouteContext

路由上下文参数,主要包含如下几个参数:

public final class RouteContext {
   
    private final SQLStatementContext sqlStatementContext;
    private final List<Object> parameters;
    private final RouteResult routeResult;
}
  • sqlStatementContext:解析引擎获取的SQLStatement
  • parameters:PreparedStatement中设置的参数,如执行insert操作setXxx代替?
  • routeResult:路由之后用来存放路由结果;
ShardingRule

分片规则,主要参数如下,这个其实和ShardingRuleConfiguration大同小异,只是重新做了一个包装;

public class ShardingRule implements BaseRule {
   
    private final ShardingRuleConfiguration ruleConfiguration;
    private final ShardingDataSourceNames shardingDataSourceNames;
    private final Collection<TableRule> tableRules;
    private final Collection<BindingTableRule> bindingTableRules;
    private final Collection<String> broadcastTables;
    private final ShardingStrategy defaultDatabaseShardingStrategy;
    private final ShardingStrategy defaultTableShardingStrategy;
    private final ShardingKeyGenerator defaultShardingKeyGenerator;
    private final Collection<MasterSlaveRule> masterSlaveRules;
    private final EncryptRule encryptRule;
  • ruleConfiguration:路由规则配置,可以理解为是ShardingRule的原始文件;
  • shardingDataSourceNames:分片的数据源名称;
  • tableRules:表路由规则,对应了用户配置的TableRuleConfiguration
  • bindingTableRules:绑定表配置,分⽚规则⼀致的主表和⼦表;
  • broadcastTables:广播表配置,所有的分⽚数据源中都存在的表;
  • defaultDatabaseShardingStrategy:默认库分片策略;
  • defaultTableShardingStrategy:默认表分片策略;
  • defaultShardingKeyGenerator:默认主键生成策略;
  • masterSlaveRules:主从规则配置,用来实现读写分离的,可配置一个主表多个从表;
  • encryptRule:加密规则配置,提供了对某些敏感数据进行加密的功能;

获取分片条件

在获取具体路由引擎和执行路由操作之前,我们需要获取分片的条件,常见的分片条件主要在Insert语句和Where语句后面;部分获取分片条件的源码如下:

    private ShardingConditions getShardingConditions(final List<Object> parameters, 
                                                     final SQLStatementContext sqlStatementContext, final SchemaMetaData schemaMetaData, final ShardingRule shardingRule) {
   
        if (sqlStatementContext.getSqlStatement() instanceof DMLStatement) {
   
            if (sqlStatementContext instanceof InsertStatementContext) {
   
                return new ShardingConditions(new InsertClauseShardingConditionEngine(shardingRule).createShardingConditions((InsertStatementContext) sqlStatementContext, parameters));
            }
            return new ShardingConditions(new WhereClauseShardingConditionEngine(shardingRule, schemaMetaData).createShardingConditions(sqlStatementContext, parameters)
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值