[Shardingsphere]数据源初始化

文章目录

  • 数据源初始化
    • 1.sharding-jdbc
    • 2.sharding-proxy

数据源初始化

1.sharding-jdbc

工厂类ShardingDataSourceFactory.createDataSource()方法在创建Sharding-JDBC的数据源实现类ShardingDataSource的同时还创建了ShardingRuleShardingRuntimeContext两个核心类的对象,如下相关源码:

public final class ShardingDataSourceFactory {
    
    /**
     * Create sharding data source.
     *
     * @param dataSourceMap data source map
     * @param shardingRuleConfig rule configuration for databases and tables sharding
     * @param props properties for data source
     * @return sharding data source
     * @throws SQLException SQL exception
     */
    public static DataSource createDataSource(
            final Map<String, DataSource> dataSourceMap, final ShardingRuleConfiguration shardingRuleConfig, final Properties props) throws SQLException {
        return new ShardingDataSource(dataSourceMap, new ShardingRule(shardingRuleConfig, dataSourceMap.keySet()), props);
    }
}

public class ShardingDataSource extends AbstractDataSourceAdapter {
    
    private final ShardingRuntimeContext runtimeContext;
    
    public ShardingDataSource(final Map<String, DataSource> dataSourceMap, final ShardingRule shardingRule, final Properties props) throws SQLException {
        super(dataSourceMap);
        checkDataSourceType(dataSourceMap);
        runtimeContext = new ShardingRuntimeContext(dataSourceMap, shardingRule, props, getDatabaseType());
    }
}

ShardingDataSource持有属性ShardingRuntimeContext,这里面又有两个重要属性DatabaseMetaData(数据库元数据信息)和ShardingSphereMetaData(元数据信息,包含数据源的元数据信息和表的元数据信息)。

ShardingRule保存了表的分库分表配置,这些配置包括分库策略以及算法、分表策略以及算法,也就是说根据一个表以及这个表的列可以从ShardingRuntimeContext中获取这个表的分库分表策略和算法。
ShardingSphereMetaData则维护了数据源和表的元数据信息,其有两个属性:DataSourceMetasTableMetas,分表表示数据源的元数据信息和表的元数据信息。

ShardingRuleConfiguration是分库分表配置的核心和入口,它可以包含多个TableRuleConfigurationMasterSlaveRuleConfiguration。每一组相同规则分片的表配置一个TableRuleConfiguration。一个TableRuleConfiguration表示一个表的分库分表策略配置,其持有两个类型为ShardingStrategyConfiguration的属性:defaultDatabaseShardingStrategyConfigdefaultTableShardingStrategyConfig,分别表示分库策略配置和分表策略配置。ShardingStrategyConfiguration有如下五种实现:
在这里插入图片描述

具体为:
StandardShardingStrategyConfiguration 支持精确分片和范围分片
ComplexShardingStrategyConfiguration 支持复杂分表
HintShardingStrategyConfiguration 强制某种策略分片
InlineShardingStrategyConfiguration 支持表达式分片
NoneShardingStrategyConfiguration 不分片
以上每种分片策略配置都关联一到两个对应的分片算法
[Shardingsphere]数据源初始化_第1张图片

分片算法由接口ShardingAlgorithm表示,其抽象子类有:
PreciseShardingAlgorithm 精确分片算法
RangeShardingAlgorithm 范围分片算法
HintShardingAlgorithm 强制分片算法
ComplexKeysShardingAlgorithm 复杂分片算法
Sharding-JDBC会使用ShardingRuleConfiguration实例化TableRule对象,源码如下:

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;
    
    public ShardingRule(final ShardingRuleConfiguration shardingRuleConfig, final Collection<String> dataSourceNames) {
        Preconditions.checkArgument(null != shardingRuleConfig, "ShardingRuleConfig cannot be null.");
        Preconditions.checkArgument(null != dataSourceNames && !dataSourceNames.isEmpty(), "Data sources cannot be empty.");
        this.ruleConfiguration = shardingRuleConfig;
        shardingDataSourceNames = new ShardingDataSourceNames(shardingRuleConfig, dataSourceNames);
        tableRules = createTableRules(shardingRuleConfig);
        broadcastTables = shardingRuleConfig.getBroadcastTables();
        bindingTableRules = createBindingTableRules(shardingRuleConfig.getBindingTableGroups());
        defaultDatabaseShardingStrategy = createDefaultShardingStrategy(shardingRuleConfig.getDefaultDatabaseShardingStrategyConfig());
        defaultTableShardingStrategy = createDefaultShardingStrategy(shardingRuleConfig.getDefaultTableShardingStrategyConfig());
        defaultShardingKeyGenerator = createDefaultKeyGenerator(shardingRuleConfig.getDefaultKeyGeneratorConfig());
        masterSlaveRules = createMasterSlaveRules(shardingRuleConfig.getMasterSlaveRuleConfigs());
        encryptRule = createEncryptRule(shardingRuleConfig.getEncryptRuleConfig());
    }
}

一个TableRule对象表示一个逻辑表的库表资源,其维护一个类型为DataNode的集合属性actualDataNodes
[Shardingsphere]数据源初始化_第2张图片
这个DataNode集合actualDataNodes表示该逻辑表对应的实际库表的集合,比如现在有两个库db0db1,每个库有两个表,逻辑表名为tborder,那么TableRule对象的属性actualDataNodes则有4个元素:

db0 tborder0
db0 tborder1
db1 tborder0
db1 tborder1

Sharding-JDBC做路由时就根据这个集合使用相应的算法进行实际的库表选取的。

2.sharding-proxy

程序的入口是org.apache.shardingsphere.shardingproxy.Bootstrap

public static void main(final String[] args) throws IOException, SQLException {
            ShardingConfiguration shardingConfig = new ShardingConfigurationLoader().load();
            logRuleConfigurationMap(getRuleConfiguration(shardingConfig.getRuleConfigurationMap()).values());
            int port = getPort(args);
            if (null == shardingConfig.getServerConfiguration().getOrchestration()) {
                startWithoutRegistryCenter(shardingConfig.getRuleConfigurationMap(), shardingConfig.getServerConfiguration().getAuthentication(), shardingConfig.getServerConfiguration().getProps(), port);
            } else {
                startWithRegistryCenter(shardingConfig.getServerConfiguration(), shardingConfig.getRuleConfigurationMap().keySet(), shardingConfig.getRuleConfigurationMap(), port);
            }
    }
    public final class ShardingConfigurationLoader {
        public ShardingConfiguration load() throws IOException {
                Collection<String> schemaNames = new HashSet<>();
                YamlProxyServerConfiguration serverConfig = loadServerConfiguration(new File(ShardingConfigurationLoader.class.getResource(CONFIG_PATH + SERVER_CONFIG_FILE).getFile()));
                File configPath = new File(ShardingConfigurationLoader.class.getResource(CONFIG_PATH).getFile());
                Collection<YamlProxyRuleConfiguration> ruleConfigurations = new LinkedList<>();
                for (File each : findRuleConfigurationFiles(configPath)) {
                    Optional<YamlProxyRuleConfiguration> ruleConfig = loadRuleConfiguration(each, serverConfig);
                    if (ruleConfig.isPresent()) {
                        Preconditions.checkState(schemaNames.add(ruleConfig.get().getSchemaName()), "Schema name `%s` must unique at all rule configurations.", ruleConfig.get().getSchemaName());
                        ruleConfigurations.add(ruleConfig.get());
                    }
                }
                Preconditions.checkState(!ruleConfigurations.isEmpty() || null != serverConfig.getOrchestration(), "Can not find any sharding rule configuration file in path `%s`.", configPath.getPath());
                Map<String, YamlProxyRuleConfiguration> ruleConfigurationMap = new HashMap<>(ruleConfigurations.size(), 1);
                for (YamlProxyRuleConfiguration each : ruleConfigurations) {
                    ruleConfigurationMap.put(each.getSchemaName(), each);
                }
                return new ShardingConfiguration(serverConfig, ruleConfigurationMap);
       }
    }

    private static void startWithoutRegistryCenter(final Map<String, YamlProxyRuleConfiguration> ruleConfigs,
                                                   final YamlAuthenticationConfiguration authentication, final Properties prop, final int port) throws SQLException {
        Authentication authenticationConfiguration = getAuthentication(authentication);
        ConfigurationLogger.log(authenticationConfiguration);
        ConfigurationLogger.log(prop);
        ShardingProxyContext.getInstance().init(authenticationConfiguration, prop);
        LogicSchemas.getInstance().init(getDataSourceParameterMap(ruleConfigs), getRuleConfiguration(ruleConfigs));
        initOpenTracing();
        ShardingProxy.getInstance().start(port);
    }
    
    private static void startWithRegistryCenter(final YamlProxyServerConfiguration serverConfig,
                                                final Collection<String> shardingSchemaNames, final Map<String, YamlProxyRuleConfiguration> ruleConfigs, final int port) {
        try (ShardingOrchestrationFacade shardingOrchestrationFacade = new ShardingOrchestrationFacade(
                new OrchestrationConfigurationYamlSwapper().swap(serverConfig.getOrchestration()), shardingSchemaNames)) {
            initShardingOrchestrationFacade(serverConfig, ruleConfigs, shardingOrchestrationFacade);
            Authentication authentication = shardingOrchestrationFacade.getConfigService().loadAuthentication();
            Properties properties = shardingOrchestrationFacade.getConfigService().loadProperties();
            ConfigurationLogger.log(authentication);
            ConfigurationLogger.log(properties);
            ShardingProxyContext.getInstance().init(authentication, properties);
            LogicSchemas.getInstance().init(shardingSchemaNames, getSchemaDataSourceParameterMap(shardingOrchestrationFacade), getSchemaRules(shardingOrchestrationFacade), true);
            initOpenTracing();
            ShardingProxy.getInstance().start(port);
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

1.首先执行load()
load()方法主要是进行加载conf目录下的文件内容,构建ShardingConfiguration对象,这个对象有两个属性:

public final class ShardingConfiguration {
    private final YamlProxyServerConfiguration serverConfiguration;
    private final Map<String, YamlProxyRuleConfiguration> ruleConfigurationMap;
}

服务配置相关参数serverConfiguration,主要是加载server.yaml得到的对象;
规则集合ruleConfigurationMap,保存的是逻辑库对应的规则信息。

2.根据配置决定是有注册中心的加载还是没有注册中心的加载。
以有注册中心为例,也就是startWithRegistryCenter函数,这里
initShardingOrchestrationFacade() 会将读到的配置——也就是服务配置信息以及规则配置等信息加载到注册中心,接下来LogicSchemas.getInstance().init()方法将逻辑库信息加载到内存,也就是保存到LogicSchemas中的属性Map logicSchemas
[Shardingsphere]数据源初始化_第3张图片
关键的属性是shardingRule,以及backendDataSourceShardingRule保存了表的分库分表配置,这些配置包括分库策略以及算法、分表策略以及算法,也就是说根据一个表以及这个表的列可以从ShardingRuntimeContext中获取这个表的分库分表策略和算法。backendDataSource则保存了数据源。

你可能感兴趣的:(sharding-sphere,数据库,java)