ShardingSphere
从软件层面对硬件资源进行管理,从而对数据库进行横向扩展,但同时也带来了一些问题。
可以直接使用一些原生支持分布式或动态扩展的数据库进行替代(对使用分库分表的选择必须要慎重
)。
数据分片
垂直分片:按照业务的方式进行拆分;核心理念是专库专用(按照业务将数据表分散到不同的数据库中)
水平分片:横向拆分(通过某些规则将数据分散至多个库或表中)
概念
SQL
水平拆分示例:订单实体
order
对应表名为t_order
,拆分为t_order_0
至t_order_9
共10张表
-
逻辑表:水平拆分的数据库(表)的相同逻辑和数据结构表的总称。示例中的
t_order
-
真实表:在分片的数据库中真实存在的物理表。示例中的
t_order_0
到t_order_9
-
数据节点:数据分片的最小单元,由数据源名称和数据表组成。示例中的
ds_0.t_order_0
-
绑定表:分片规则一致的主表和子表。如
t_order
和t_order_item
都按照order_id
分片,此两张表互为绑定表关系
(绑定表之间的多表关联查询不会出现笛卡尔积关联,关联查询效率将大大提升)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);
t_order
在FROM的最左侧,ShardingSphere
将会以它作为整个绑定表的主表。 所有路由计算将会只使用主表的策略,那么t_order_item
表的分片计算将会使用t_order
的条件 -
广播表:所有的分片数据源中都存在的表,表结构和表中的数据在每个数据库中都完全一致。适用于数据量不大且需要与海量数据的表进行关联查询的场景。例:字典表
分片
分片键
用于分片的数据库字段,是将数据库(表)水平拆分的关键字段;
SQL
中如果无分片字段,将执行全路由,性能较差;
除了单分片字段,ShardingSphere
也支持根据多个字段进行分片。
分片算法
通过分片算法将数据分片,支持通过=
、>=
、<=
、>
、<
、BETWEEN
和IN
分片;
分片算法需要自行实现;
目前提供四种分片算法(由于算法实现与业务相关,并未内置分片算法,而是通过分片策略提炼各种场景,提供更高层级的抽象,由开发者自行实现)
-
精确分片算法
对应
PreciseShardingAlgorithm
,用于处理使用单一键作为分片键的=
与IN
进行分片的场景;
需配合StandardShardingStrategy
使用 -
范围分片算法
对应
RangeShardingAlgorithm
,用于处理使用单一键作为分片键的BETWEEN AND
、>
、<
、>=
、<=
进行分片的场景;
需配合StandardShardingStrategy
使用 -
符合分片算法
对应
ComplexKeysShardingAlgorithm
,用于处理使用多键作为分片键进行分片的场景,包含多个分片键的逻辑较复杂,需要开发者自行处理复杂度;
需配合ComplexShardingStrategy
使用 -
Hint
分片算法对应
HintShardingAlgorithm
,用于处理使用Hint
进行分片的场景;
需配合HintShardingStrategy
使用
分片策略
包含分片键和分片算法,由于算法的独立性,将其独立抽离。真正可用于分片操作的是分片键+分片算法,即分片策略,分为5种:
-
标准分片策略
- 对应
StandardShardingStrategy
。提供对SQL
中的=
、>
、<
、>=
、<=
、IN
和BETWEEN AND
的分片操作支持; - 只支持单分片键,提供
PreciseShardingAlgorithm
和RangeShardingAlgorithm
两个分片算法; PreciseShardingAlgorithm
必选,用于处理=
和IN
的分片RangeShardingAlgorithm
可选,用于处理>
、<
、>=
、<=
、BETWEEN AND
- 如果不配置
RangeShardingAlgorithm
,SQL
中的BETWEEN AND
将按照全库路由处理
- 对应
-
复合分片策略
- 对应
ComplexShardingStrategy
,提供对SQL语句中的=
,>
,<
,>=
,<=
,IN
和BETWEEN AND
的分片操作支持 - 支持多分片键(直接将分片键值组合以及分片操作符透传至分片算法,由开发者自行实现)
- 对应
-
行表达式分片策略
- 对应
InlineShardingStrategy
,使用Groovy
表达式,提供对SQL
语句中的=
和IN
的分片操作支持 - 只支持单分片键
- 可以通过简单的配置使用
(例:t_user_$->{u_id % 8}
表示t_user
表根据u_id
模8
,而分成8
张表,表名称为t_user_0
到t_user_7
)
- 对应
-
Hint
分片策略对应
HintShardingStrategy
。通过Hint
指定分片值而非从SQL
中提取分片值的方式进行分片的策略 -
不分片策略
对应
NoneShardingStrategy
。不分片的策略
SQL Hint
对于分片字段为非SQL
字段,而是其他外置条件的场景,可使用SQL Hint
灵活的注入分片字段
SQL Hint
支持通过Java API
和SQL注释
(待实现)两种方式使用
配置
分片规则
总入口,包含数据源配置、表配置、绑定表配置及读写分离配置等
数据源配置
真实数据源列表
表配置
逻辑表名称、数据节点与分表规则的配置
数据节点配置
配置逻辑表与真实表的映射关系。分为均匀分布与自定义分布两种方式
- 均匀分布:数据表在每个数据源内呈现均匀分布的态势
- 自定义分布:数据表呈现有特定规则的分布
## 均匀分布
db0
├── t_order0
└── t_order1
db1
├── t_order0
└── t_order1
# 数据节点配置:db0.t_order0, db0.t_order1, db1.t_order0, db1.t_order1
## 自定义分布
db0
├── t_order0
└── t_order1
db1
├── t_order2
├── t_order3
└── t_order4
# 数据节点配置:db0.t_order0, db0.t_order1, db1.t_order2, db1.t_order3, db1.t_order4
分片策略配置
- 数据源分片策略:对应
DatabaseShardingStrategy
,配置数据被分配的目标数据源 - 表分片策略:对应
TableShardingStrategy
,配置数据被分配的目标表
(目标表存在于该数据的目标数据源内,故表分片策略依赖于数据源分片策略)
两种策略API
完全相同
自增主键生成策略
客户端生成自增主键替换数据库原生的自增主键,做到分布式主键无重复
内核剖析
核心由SQL解析 => 执行器优化 => SQL路由 => SQL改写 => SQL执行 => 结果归并
流程组成
- SQL解析:分为词法解析和语法解析
先通过词法解析器将SQL拆分为一个个不可再分的单词。再使用语法解析器对SQL进行理解,并最终提炼出解析上下文
解析上下文包括表、选择项、排序项、分组项、聚合函数、分页信息、查询条件以及可能需要修改的占位符的标记 - 执行器优化:合并和优化分片条件,如
OR
等 - SQL路由:根据解析上下文匹配用户配置的分片策略,并生成路由路径。目前支持分片路由和广播路由
- SQL改写:将SQL改写为在真实数据库中可以正确执行的语句。SQL改写分为正确性改写和优化改写
- SQL执行:多线程执行器异步执行
- 结果归并:将多个执行结果集归并以便于通过统一的
JDBC
接口输出
包括流式归并、内存归并和使用装饰者模式的追加归并
这里只是记录了典型的ShardingJDBC
使用相关的配置,仅仅是对于了解ShardingJDBC
如何使用的一个入门,更深入的配置及原理部分,可以直接参考官方文档