sharding-sphere主要的配置有四类,一个是数据库读写分离,主备数据源配置,一个是数据表配置,一个是分片规则配置。分别如下:
类名 | 介绍 |
---|---|
MasterSlaveRuleConfiguration | 主备数据源配置 |
ShardingRuleConfiguration | 分片规则配置 |
TableRuleConfiguration | 表配置 |
主备数据源配置:MasterSlaveRuleConfiguration
public final class MasterSlaveRuleConfiguration {
//名称
private final String name;
//主数据源
private final String masterDataSourceName;
//从数据源
private final Collection slaveDataSourceNames;
//负载均衡算法
private MasterSlaveLoadBalanceAlgorithm loadBalanceAlgorithm;
}
MasterSlaveLoadBalanceAlgorithm算法有两种实现,根据名称,主数据源名称,从数据源列表选择一个数据源。但默认算法实现过程中并未使用前两个字段,用户自定义使用的过程中可以使用。
public interface MasterSlaveLoadBalanceAlgorithm {
String getDataSource(String name, String masterDataSourceName, List slaveDataSourceNames);
}
//随机算法
public final class RandomMasterSlaveLoadBalanceAlgorithm implements MasterSlaveLoadBalanceAlgorithm {
@Override
public String getDataSource(final String name, final String masterDataSourceName, final List slaveDataSourceNames) {
return slaveDataSourceNames.get(new Random().nextInt(slaveDataSourceNames.size()));
}
}
//轮询算法
public final class RoundRobinMasterSlaveLoadBalanceAlgorithm implements MasterSlaveLoadBalanceAlgorithm {
private static final ConcurrentHashMap COUNT_MAP = new ConcurrentHashMap<>();
@Override
public String getDataSource(final String name, final String masterDataSourceName, final List slaveDataSourceNames) {
AtomicInteger count = COUNT_MAP.containsKey(name) ? COUNT_MAP.get(name) : new AtomicInteger(0);
COUNT_MAP.putIfAbsent(name, count);
count.compareAndSet(slaveDataSourceNames.size(), 0);
return slaveDataSourceNames.get(count.getAndIncrement() % slaveDataSourceNames.size());
}
}
从配置上看,符合一主多从的结构,主数据源只有一个,从数据源有多个。官方文档也证实了这一点。官方地址请点击我
分片规则配置:
public final class ShardingRuleConfiguration {
//默认数据源名称
private String defaultDataSourceName;
//表规则配置
private Collection tableRuleConfigs = new LinkedList<>();
//相同表分片规则的组,如果表分片规则相同,则可以放在一个组里。
private Collection bindingTableGroups = new LinkedList<>();
//默认数据库的分片算法配置
private ShardingStrategyConfiguration defaultDatabaseShardingStrategyConfig;
//默认表的分片算法配置
private ShardingStrategyConfiguration defaultTableShardingStrategyConfig;
//默认键的生成工具类
private KeyGenerator defaultKeyGenerator;
//主备配置信息
private Collection masterSlaveRuleConfigs = new LinkedList<>();
}
能够看到,所有的配置信息其实都是配在分片配置中。
表配置信息TableRuleConfiguration
public final class TableRuleConfiguration {
//逻辑表名
private String logicTable;
//真实的数据节点名称
private String actualDataNodes;
//数据库分片算法配置
private ShardingStrategyConfiguration databaseShardingStrategyConfig;
//表分片算法配置
private ShardingStrategyConfiguration tableShardingStrategyConfig;
//自动生成键的名称
private String keyGeneratorColumnName;
//自动生成键的工具类
private KeyGenerator keyGenerator;
private String logicIndex;
}
看完了分片规则配置,再来看看分片规则,毕竟分片规则的信息都是由分片配置中来的。
ShardingRule
public final class ShardingRule {
//分片规则配置
private final ShardingRuleConfiguration shardingRuleConfig;
//数据源信息
private final ShardingDataSourceNames shardingDataSourceNames;
//表规则
private final Collection tableRules = new LinkedList<>();
//相同分片规则的表规则
private final Collection bindingTableRules = new LinkedList<>();
//数据库配置
private final ShardingStrategy defaultDatabaseShardingStrategy;
//默认表分片规则
private final ShardingStrategy defaultTableShardingStrategy;
//默认字段生成器
private final KeyGenerator defaultKeyGenerator;
//主备配置信息
private final Collection masterSlaveRules = new LinkedList<>();
}
这些信息怎么来的?看构造方法:
public ShardingRule(final ShardingRuleConfiguration shardingRuleConfig, final Collection dataSourceNames) {
this.shardingRuleConfig = shardingRuleConfig;
shardingDataSourceNames = new ShardingDataSourceNames(shardingRuleConfig, dataSourceNames);
//初始化表配置规则
for (TableRuleConfiguration each : shardingRuleConfig.getTableRuleConfigs()) {
tableRules.add(new TableRule(each, shardingDataSourceNames));
}
//分片规则相同组的放在一起
for (String group : shardingRuleConfig.getBindingTableGroups()) {
List tableRulesForBinding = new LinkedList<>();
for (String logicTableNameForBindingTable : StringUtil.splitWithComma(group)) {
tableRulesForBinding.add(getTableRule(logicTableNameForBindingTable));
}
bindingTableRules.add(new BindingTableRule(tableRulesForBinding));
}
//默认数据库分片规则
defaultDatabaseShardingStrategy = null == shardingRuleConfig.getDefaultDatabaseShardingStrategyConfig()
? new NoneShardingStrategy() : ShardingStrategyFactory.newInstance(shardingRuleConfig.getDefaultDatabaseShardingStrategyConfig());
//默认表分片算法
defaultTableShardingStrategy = null == shardingRuleConfig.getDefaultTableShardingStrategyConfig()
? new NoneShardingStrategy() : ShardingStrategyFactory.newInstance(shardingRuleConfig.getDefaultTableShardingStrategyConfig());
//初始化默认字段生成方式
defaultKeyGenerator = null == shardingRuleConfig.getDefaultKeyGenerator() ? new DefaultKeyGenerator() : shardingRuleConfig.getDefaultKeyGenerator();
//主备规则配置
for (MasterSlaveRuleConfiguration each : shardingRuleConfig.getMasterSlaveRuleConfigs()) {
masterSlaveRules.add(new MasterSlaveRule(each));
}
}
表分片规则TableRule
public final class TableRule {
//逻辑实体表
private final String logicTable;
//实际存储的表节点数据
private final List actualDataNodes;
private final ShardingStrategy databaseShardingStrategy;
private final ShardingStrategy tableShardingStrategy;
//默认生成值的表字段名称
private final String generateKeyColumn;
//生成器
private final KeyGenerator keyGenerator;
private final String logicIndex;
}
DataNode为实际存储的节点表的信息,logicTable为逻辑实体表的表名,官方文档是这样介绍的:
在这里,t_order为logicTable属性,t_order_0~t_order_9为actualDataNodes的信息。
DataNode节点数据结构为:
public final class DataNode {
private static final String DELIMITER = ".";
//数据源名称
private final String dataSourceName;
//表名称
private final String tableName;
}
BindingTableRule
public final class BindingTableRule {
private final List tableRules;
}
BindingTableRule很简单,就是有相同分片规则的一些表的集合,由一个表就能获取到其他的表的分片规则。
MasterSlaveRule
public final class MasterSlaveRule {
//name
private final String name;
//主数据源节点名称
private final String masterDataSourceName;
//从数据源节点名称
private final Collection slaveDataSourceNames;
//负载均衡算法
private final MasterSlaveLoadBalanceAlgorithm loadBalanceAlgorithm;
}
ShardingRule分片规则的API如下:
方法名 | 说明 |
---|---|
Optional |
根据逻辑表名获取实体表名 |
tryFindTableRuleByActualTable(final String actualTableName) | 根据真实表名获取表规则,遍历DataNode节点 |
TableRule getTableRule(final String logicTableName) | 获取表规则 |
getTableRule(final String logicTableName) | 根据逻辑表名称获取表规则信息和tryFindTableRuleByLogicTable的区别在于,找不到的时候,会初始化一个 |
ShardingStrategy getDatabaseShardingStrategy(final TableRule tableRule) | 获取数据库分片算法 |
ShardingStrategy getTableShardingStrategy(final TableRule tableRule) | 获取表分片算法 |
isAllBindingTables(final Collection |
是否所有表都有相同的分片规则 |
isAllInDefaultDataSource(final Collection |
是否所有的表都属于同一个默认的数据源 |
findBindingTableRule(final String logicTable) | 查找逻辑表名为logicTable的实体表规则 |
isShardingColumn(final Column column) | 是否是分片项的键 |
getGenerateKeyColumn(final String logicTableName) | 获取自动生成的键的项 |
generateKey(final String logicTableName) | 生成默认列信息 |
getLogicTableName(final String logicIndexName) | 根据logicIndexName获取逻辑表名 |
findDataNode(final String logicTableName) | 获取数据节点,如果有多个,则取第一个 |
DataNode findDataNode(final String dataSourceName, final String logicTableName) | 根据逻辑实体名获取数据节点 |
isLogicIndex(final String logicIndexName, final String logicTableName) | 是否是逻辑表索引,逻辑索引名,逻辑表名称 |
getMasterDataSourceName(final String masterSlaveRuleName) | 获取主数据源名称 |