[Shardingsphere]数据源初始化

15 篇文章 0 订阅
8 篇文章 1 订阅

数据源初始化

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 不分片
以上每种分片策略配置都关联一到两个对应的分片算法
在这里插入图片描述

分片算法由接口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
在这里插入图片描述
这个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<String, LogicSchema> logicSchemas
在这里插入图片描述
关键的属性是shardingRule,以及backendDataSourceShardingRule保存了表的分库分表配置,这些配置包括分库策略以及算法、分表策略以及算法,也就是说根据一个表以及这个表的列可以从ShardingRuntimeContext中获取这个表的分库分表策略和算法。backendDataSource则保存了数据源。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在Spring Boot中,可以使用application.yml或application.properties文件来配置数据源。其中,application.yml是使用YAML语言编写的配置文件,而application.properties则是使用键值对的形式编写的配置文件。 下面是使用application.yml来配置数据源的示例: ``` spring: datasource: url: jdbc:mysql://localhost:3306/mydb username: root password: password driver-class-name: com.mysql.jdbc.Driver ``` 其中,url、username、password和driver-class-name四个属性分别表示数据源的连接地址、用户名、密码和驱动类名。 如果需要在应用程序启动时初始化数据,可以使用Spring Boot提供的ApplicationRunner或CommandLineRunner接口。这两个接口都只有一个run方法,可以在其中编写初始化数据的代码。 下面是使用ApplicationRunner接口初始化数据的示例: ``` @Component public class DataLoader implements ApplicationRunner { @Autowired private UserRepository userRepository; @Override public void run(ApplicationArguments args) throws Exception { User user1 = new User("John", "Doe"); User user2 = new User("Jane", "Doe"); userRepository.save(user1); userRepository.save(user2); } } ``` 在上面的示例中,使用@Autowired注解注入了一个UserRepository对象,并在run方法中向数据库中插入了两条用户记录。 需要注意的是,ApplicationRunner和CommandLineRunner接口都是在Spring Boot应用程序启动完成后执行的,因此如果需要在应用程序启动前执行初始化操作,可以考虑使用Spring Boot提供的ApplicationListener接口。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值