ShardingSphere分库分表应用
一、概述
Sharding-JDBC 最早是当当网内部使用的一款分库分表框架,到2017年的时候才开始对外开源,这几年在大量社区贡献者的不断迭代下,功能也逐渐完善,现已更名为 ShardingSphere ,2020年4⽉16⽇正式成为 Apache 软件基⾦会的顶级项⽬。
ShardingSphere生态包含三款开源分布式数据库中间件解决方案,Sharding-JDBC、Sharding-Proxy、ShardingSidecar。
1.1、Sharding-JDBC
Sharding-JDBC是比较常用的一个组件,它定位的是一个增强版的JDBC驱动,简单来说就是在应用端来完成数据库分库分表相关的路由和分片操作。
目前最常用组件,在项目内引入Sharding-JDBC的依赖,我们的业务代码在操作数据库的时候,就会通过ShardingJDBC的代码连接到数据库。也就是分库分表的一些核心动作,比如SQL解析,路由,执行,结果处理,都是由它来完成的,它工作在客户端。
Registry Center表示注册中心,用来实现集中化分片配置规则管理、动态配置、以及数据源等信息。
1.2、Sharding-Proxy
Sharding-Proxy有点类似于Mycat,它是提供了数据库层面的代理,简单来说,以前的应用是直连数据库,引入了Sharding-Proxy之后,现在的应用是直连Sharding-Proxy,然后Sharding-Proxy通过处理之后再转发到mysql中。
这种方式的好处在于,用户不需要感知到分库分表的存在,相当于正常访问mysql。目前ShardingProxy支持Mysql和PostgreSQL两种数据库协议。
1.3、Sharding-Sidecar
看到Sidecar,应该就能想到服务网格架构,它主要定位于 Kubernetes 的云原生数据库代理,以Sidecar 的形式代理所有对数据库的访问。目前Sharding-Sidecar还处于开发阶段未发布
二、Sharding-JDBC
Java应用程序通过Sharding-JDBC驱动访问数据库,而在Sharding-JDBC中,它会根据相关配置完成分库分表路由、分布式事务等功能,Sharding-JDBC相当于增强了JDBC驱动的功能。
在Sharding-JDBC中,有一些表的概念:逻辑表、真实表、分片键、数据节点、
动态表、广播表、绑定表。
2.1、逻辑表
逻辑表可以理解为数据库中的视图,是一张虚拟表。可以映射到一张物理表,也可以由多张物理表组成,这些物理表可以来自于不同的数据源。
针对逻辑表操作时,会根据分片规则映射到实际的物理表进行相关事务操作,逻辑表会在SQL解析和路由时被替换成真实的表名。
spring.shardingsphere.rules.sharding.tables.t_order.actual-data-nodes=ds-$->{0.}.t_order_$->{0.}
2.2、广播表
广播表也叫全局表,也就是它会存在于多个库中冗余,避免跨库查询问题。
比如省份、字典等一些基础数据,为了避免分库分表后关联表查询这些基础数据存在跨库问题,所以可以把这些数据同步给每一个数据库节点,这个就叫广播表。
# 广播表, 其主节点是ds0
spring.shardingsphere.sharding.broadcast-tables=t_config
spring.shardingsphere.sharding.tables.t_config.actual-data-nodes=ds$->{0}.t_config
2.3、绑定表
我们有些表的数据是存在逻辑的主外键关系的,比如订单表order_info,存的是汇总的商品数,商品金额;订单明细表order_detail,是每个商品的价格,个数等等。或者叫做从属关系,父表和子表的关系。他们之间会经常有关联查询的操作,如果父表的数据和子表的数据分别存储在不同的数据库,跨库关联查询也比较麻烦。绑定表就是把父表和数据和从属于父表的数据落到一个节点上。
# 绑定表规则,多组绑定规则使用数组形式配置
spring.shardingsphere.rules.sharding.binding-tables=t_order,t_order_item
三、 分片
Sharding-JDBC内置了很多常用的分片策略,这些算法主要针对两个维度:
- 数据源分片
- 数据表分片
Sharding-JDBC的分片策略包含了分片键和分片算法;
- 分片键,用于分片的数据库字段,是将数据库(表)水平拆分的关键字段。例:将订单表中的订单主键的尾数取模分片,则订单主键为分片字段。
SQL中如果无分片字段,将执行全路由,性能较差。 除了对单分片字段的支持,ShardingSphere也支持根据多个字段进行分片 - 分片算法,就是用来实现分片的计算规则。Sharding-JDBC提供内置了多种分片算法,包含四种类型
- 自动分片算法
- 标准分片算法
- 复合分片算法
- Hinit分片算法
3.1、自动分片算法
自动分片算法,就是根据我们配置的算法表达式完成数据的自动分发功能,在Sharding-JDBC中提供了
五种自动分片算法
- 取模分片算法
- 哈希取模分片算法
- 基于分片容量的范围分片算法
- 基于分片边界的范围分片算法
- 自动时间段分片算法
3.2、标准分片算法
标准分片策略( StandardShardingStrategy ),它只支持对单个分片健(字段)为依据的分库分表,Sharding-JDBC提供了两种算法实现
- 行表达式分片算法
- 时间范围分片算法
3.3、复合分片算法
SQL 语句中有 > , >= , <= , < , = , IN 和 BETWEEN AND 等操作符,不同的是复合分片策略支持对多个分片健操作
3.4、Hinit分片算法
强制路由算法,在其他的算法中需要从sql中解析出对应的分片键和值,而这个算法是通过API强制设置的方式
3.5、读写分离
# 配置读写分离
# 配置从库选择策略,提供轮询与随机,这里选择用轮询
sharding.jdbc.config.masterslave.load-balance-algorithm-type=round_robin
sharding.jdbc.config.masterslave.name=ms
sharding.jdbc.config.masterslave.master-data-source-name=master
sharding.jdbc.config.masterslave.slave-data-source-names=slave
除了默认提供了分片算法之外,我们可以根据实际需求自定义分片算法,Sharding-JDBC同样提供了几种类型的SPI扩展实现。
- 标准分片算法
- 复合分片算法
- Hinit分片策略
- 不分片策略