1.ShardingSphere数据分片的概念
1.1 主要通过分库和分表进行数据的拆分来使得各个表的数据量保持在阈值以下,以及对流量进行疏导应对高访问量,是应对高并发和海量数据系统的有效手段。 数据分片的拆分方式又分为垂直分片和水平分片(详情见官网:数据分片 :: ShardingSphere)
垂直分片:按照业务拆分的方式称为垂直分片,又称为纵向拆分,它的核心理念是专库专用。 在拆分之前,一个数据库由多个数据表构成,每个表对应着不同的业务。而拆分之后,则是按照业务将表进行归类,分布到不同的数据库中,从而将压力分散至不同的数据库。 下图展示了根据业务需要,将用户表和订单表垂直分片到不同的数据库的方案
垂直分片往往需要对架构和设计进行调整。通常来讲,是来不及应对互联网业务需求快速变化的;而且,它也并无法真正的解决单点瓶颈。 垂直拆分可以缓解数据量和访问量带来的问题,但无法根治。如果垂直拆分之后,表中的数据量依然超过单节点所能承载的阈值,则需要水平分片来进一步处理
水平分片:水平分片又称为横向拆分。 相对于垂直分片,它不再将数据根据业务逻辑分类,而是通过某个字段(或某几个字段),根据某种规则将数据分散至多个库或表中,每个分片仅包含数据的一部分。 例如:根据主键分片,偶数主键的记录放入0库(或表),奇数主键的记录放入1库(或表),如下图所示。
用于分片的数据库字段,是将数据库(表)水平拆分的关键字段。例:将订单表中的订单主键的尾数取模分片,则订单主键为分片字段。 SQL中如果无分片字段,将执行全路由,性能较差。 除了对单分片字段的支持,ShardingSphere也支持根据多个字段进行分片
2.分片算法
通过分片算法将数据分片,支持通过=
、>=
、<=
、>
、<
、BETWEEN
和IN
分片。分片算法需要应用方开发者自行实现,可实现的灵活度非常高 目前提供4种分片算法。由于分片算法和业务实现紧密相关,因此并未提供内置分片算法,而是通过分片策略将各种场景提炼出来,提供更高层级的抽象,并提供接口让应用开发者自行实现分片算法
用于处理使用单一键作为分片键的=与IN进行分片的场景。需要配合StandardShardingStrategy使用
package com.shardingsphere.algorithm; import org.apache.shardingsphere.api.sharding.standard.PreciseShardingAlgorithm; import org.apache.shardingsphere.api.sharding.standard.PreciseShardingValue; import java.util.Collection; public class DefaultModuloPreciseShardingAlgorithm implements PreciseShardingAlgorithm{ @Override public String doSharding(Collection availableTargetNames, PreciseShardingValue shardingValue) { String modulo = String.valueOf(shardingValue.getValue() % availableTargetNames.size()); for (String targetName : availableTargetNames) { if (targetName.endsWith(modulo)) return targetName; } throw new UnsupportedOperationException(); } }
如以上精准分片算法PreciseShardingAlgorithm 通过自定义的字段 进行奇偶数进行分库分表 (注意:进行分片的字段不能进行修改 如根据age进行分库 去修改age字段的话 就会报以下错误)
package com.shardingsphere.algorithm; import org.apache.shardingsphere.api.sharding.standard.RangeShardingAlgorithm; import org.apache.shardingsphere.api.sharding.standard.RangeShardingValue; import java.util.Collection; import java.util.LinkedHashSet; import java.util.stream.Collectors; public class DefaultModuloRangeShardingAlgorithm implements RangeShardingAlgorithm{ @Override public Collection doSharding(Collection availableTargetNames, RangeShardingValue shardingValue) { Long lower = shardingValue.getValueRange().lowerEndpoint(); Long upper = shardingValue.getValueRange().upperEndpoint(); Collection result = new LinkedHashSet<>(); for (Long i = lower; i <= upper; i++) { if (result.size() == availableTargetNames.size()) break; String modulo = String.valueOf(i % availableTargetNames.size()); result.addAll(availableTargetNames.stream().filter(m -> m.endsWith(modulo)).collect(Collectors.toList())); } return result; } }
package com.shardingsphere.algorithm; import org.apache.shardingsphere.api.sharding.complex.ComplexKeysShardingAlgorithm; import org.apache.shardingsphere.api.sharding.complex.ComplexKeysShardingValue; import java.util.Collection; public class DefaultComplexKeysShardingAlgorithm implements ComplexKeysShardingAlgorithm{ @Override public Collection doSharding(Collection availableTargetNames, ComplexKeysShardingValue shardingValue) { // 多片键的精确值场景 shardingValue.getColumnNameAndShardingValuesMap(); // 多片键的范围值场景 shardingValue.getColumnNameAndRangeValuesMap(); // 根据以上两种情况来筛选数据节点: 数据源、物理表... return availableTargetNames; } }
package com.shardingsphere.algorithm; import org.apache.shardingsphere.api.hint.HintManager; import org.apache.shardingsphere.api.sharding.hint.HintShardingAlgorithm; import org.apache.shardingsphere.api.sharding.hint.HintShardingValue; import java.util.Collection; import java.util.LinkedHashSet; /** * @see HintManager 指定的外部路由值来筛选目标库、表 */ public class DefaultHintShardingAlgorithm implements HintShardingAlgorithm{ @Override public Collection doSharding(Collection availableTargetNames, HintShardingValue shardingValue) { Collection result = new LinkedHashSet<>(); for (String each : availableTargetNames) { for (Long value : shardingValue.getValues()) { if (each.endsWith(String.valueOf(value))) { result.add(each); } } } return result; } } 3.分片策略
t_user_$->{u_id % 8}
表示t_user表根据u_id模8,而分成8张表,表名称为t_user_0
到t_user_7
最后附上代码: https://gitee.com/hezhipeng_ek/shardingsphere.git