shardingsphere基础介绍
# 一、什么是 ShardingSphere
# 1.1、介绍
Apache ShardingSphere 是一款分布式的数据库生态系统, 可以将任意数据库转换为分布式数据库,并通过数据分片、弹性伸缩、加密等能力对原有数据库进行增强。
ShardingSphere-JDBC
ShardingSphere-JDBC 定位为轻量级 Java 框架,在 Java 的 JDBC 层提供的额外服务,采用无中心化架构,与应用程序共享资源,适用于 Java 开发的高性能的轻量级 OLTP 应用;
ShardingSphere-Proxy
ShardingSphere-Proxy 定位为透明化的数据库代理端, 提供静态入口以及异构语言的支持,独立于应用程序部署,适用于 OLAP 应用以及对分片数据库进行管理和运维的场景
# 1.2、发展
# 二、核心概念
# 2.1、真实表
真实存在的物理表
例如:订单表t_order数据根据主键拆分为 10 张表,分别是 t_order_0 到 t_order_9,其中 t_order_0 到 t_order_9就是真实表
# 2.2、逻辑表
相同结构的水平拆分数据库(表)的逻辑名称,是 SQL 中表的逻辑标识
例如:上个示例中表的逻辑标识,其中t_order是 t_order_0 到 t_order_9的逻辑表
# 2.3、绑定表
指分片规则一致的一组分片表
例如:t_order 表和 t_order_item 表,均按照 order_id分片,并且使用 order_id 进行关联,则此两张表互为绑定表关系
举例说明:
SELECT i.* FROM t_order o JOIN t_order_item i ON o.order_id=i.order_id WHERE o.order_id in (10, 11);
1其中 t_order 表由于指定了分片条件,ShardingSphere 将会以它作为整个绑定表的主表。所有路由计算将会只使用主表的策略,那么 t_order_item 表的分片计算将会使用 t_order 的条件
在配置绑定表关系,并且使用 order_id 进行关联后,路由的 SQL 应该为 2 条:
SELECT i.* FROM t_order_0 o JOIN t_order_item_0 i ON o.order_id=i.order_id WHERE o.order_id in (10, 11); SELECT i.* FROM t_order_1 o JOIN t_order_item_1 i ON o.order_id=i.order_id WHERE o.order_id in (10, 11);
1
2
3在不配置绑定表关系时,假设分片键 order_id 将数值 10 路由至第 0 片,将数值 11 路由至第 1 片,那么路由后的 SQL 应该为 4 条,它们呈现为笛卡尔积
SELECT i.* FROM t_order_0 o JOIN t_order_item_0 i ON o.order_id=i.order_id WHERE o.order_id in (10, 11); SELECT i.* FROM t_order_0 o JOIN t_order_item_1 i ON o.order_id=i.order_id WHERE o.order_id in (10, 11); SELECT i.* FROM t_order_1 o JOIN t_order_item_0 i ON o.order_id=i.order_id WHERE o.order_id in (10, 11); SELECT i.* FROM t_order_1 o JOIN t_order_item_1 i ON o.order_id=i.order_id WHERE o.order_id in (10, 11);
1
2
3
4
# 2.4、广播表
指所有的分片数据源中都存在的表,表结构及其数据在每个数据库中均完全一致。适用于数据量不大且需要与海量数据的表进行关联查询的场景
例如:字典表
# 2.5、单表
指所有的分片数据源中仅唯一存在的表。适用于数据量不大且无需分片的表
# 2.6、数据节点
数据分片的最小单元,由数据源名称和真实表组成,逻辑表与真实表的映射关系
例如:
db0 ├── t_order0 └── t_order1 db1 ├── t_order0 └── t_order1
1
2
3
4
5
6数据节点的配置如下:
db0.t_order0, db0.t_order1, db1.t_order0, db1.t_order1
1
# 2.7、分片策略
分片策略 = 分片算法 + 分片键
分片键
用于将数据库(表)水平拆分的数据库字段
例:将订单表中的订单主键的尾数取模分片,则订单主键为分片字段。SQL 中如果无分片字段,将执行全路由,性能较差
分片算法
用于将数据分片的算法,支持 =、>=、<=、>、<、BETWEEN 和 IN 进行分片
# 2.7.1、行表达式
对应InlineShardingStragey。使用Groovy的表达式,提供对SQL语句种的=和in的分片操作支持,只支持单分片键。对于简单的分片算法,可以通过简单的配置使用,从而避免繁琐的Java代码开发
例如,以下行表达式:
${['online', 'offline']}_table${1..3}
1最终会解析为:
online_table1, online_table2, online_table3, offline_table1, offline_table2,offline_table3
1
# 2.7.2、标准分片策略
对应StandardShardingStrategy.提供对SQL语句中的=,in和between and 的分片操作支持。StandardShardingStrategy只支持单分片键。提供PreciseShardingAlgorithm和RangeShardingAlgorithm两个分片算法
- PreciseShardingAlgorithm是必选的,用于处理=和IN的分片
- RangeShardingAlgorithm是可选的,是用于处理Betwwen and分片,如果不配置和RangeShardingAlgorithm,SQL的Between AND 将按照全库路由处理。
# 2.7.3、复合分片策略
对应ComplexShardingStrategy。ComplexShardingStrategy支持多分片键,由于多分片键之间的关系复杂,因此并未进行过多的封装,而是直接将分片键组合以及分片操作符透传至分片算法,完全由开发者自己实现,提供最大的灵活度。
# 2.7.4、Hint分片策略
对应 HintShardingStrategy。通过Hint而非SQL解析的方式分片的策略。对于分片字段非SQL决定,而是由其他外置条件决定的场景,可使用SQL hint灵活的注入分片字段。
例如:按照用户登录的时间,主键等进行分库,而数据库中并无此字段。SQL hint支持通过Java API和SQL注解两种方式使用。让分库分表更加灵活。
# 三、SQL执行过程
核心由 SQL 解析 => 执行器优化 => SQL 路由 => SQL 改写 => SQL 执行 => 结果归并的流程组成。
# 2.1、SQL 解析
分为词法解析和语法解析。 先通过词法解析器将 SQL 拆分为一个个不可再分的单词。再使用语法解析器对 SQL 进行理解,并最终提炼出解析上下文。 解析上下文包括表、选择项、排序项、分组项、聚合函数、分页信息、查询条件以及可能需要修改的占位符的标记。
# 2.2、执行器优化
合并和优化分片条件,如 OR 等。
# 2.3、SQL 路由
根据解析上下文匹配用户配置的分片策略,并生成路由路径。目前支持分片路由和广播路由。
# 2.4、SQL 改写
将 SQL 改写为在真实数据库中可以正确执行的语句。SQL 改写分为正确性改写和优化改写。
# 2.5、SQL 执行
通过多线程执行器异步执行。
# 2.6、结果归并
将多个执行结果集归并以便于通过统一的 JDBC 接口输出。结果归并包括流式归并、内存归并和使用装饰者模式的追加归并这几种方式。
参考: