分库分表实战及中间件(二)
前言
分库分表实战及中间件(一)中我们使用了在代码中使用硬编码的方式手动定义路由规则以及获取不同表
进行分表设计。
此篇使用中间件来进行分表操作,这儿使用,具体详情可以看官方连接。
ShardingSphere
简介
Apache ShardingSphere是一款开源的分布式数据库中间件组成的生态圈。它由Sharding-JDBC、Sharding-Proxy和Sharding-Sidecar(规划中)这3款相互独立的产品组成。 他们均提供标准化的数据分片、分布式事务和数据库治理功能,可适用于如Java同构、异构语言、容器云原生等各种多样化的应用场景。
ShardingSphere项目状态如下:
ShardingSphere定位为关系型数据库中间件,旨在充分合理地在分布式的场景下利用关系型数据库的计算和存储能力,而并非实现一个全新的关系型数据库。
具体分为三部分:
- Sharding-JDBC:被定位为轻量级Java框架,在Java的JDBC层提供的额外服务,以jar包形式使用。
- Sharding-Proxy:被定位为透明化的数据库代理端,提供封装了数据库二进制协议的服务端版本,用于完成对异构语言的支持。
- Sharding-Sidecar:被定位为Kubernetes或Mesos的云原生数据库代理,以DaemonSet的形式代
理所有对数据库的访问。
具体之间的关系如下图所示:
我们的应用层使用Sharding-JDBC对数据进行操作,然后可以由于Sharding-Proxy进行代理,
Sharding-JDBC、Sharding-Proxy和Sharding-Sidecar三者区别如下:
Sharding-JDBC
Sharding-JDBC定位为轻量级Java框架,在Java的JDBC层提供的额外服务。 它使用客户端直连数据库,以jar包形式提供服务,无需额外部署和依赖,可理解为增强版的JDBC驱动,完全兼容JDBC和各种ORM框架的使用。
- 适用于任何基于Java的ORM框架,如:JPA, Hibernate, Mybatis, Spring JDBC Template或直接使用JDBC。
- 基于任何第三方的数据库连接池,如:DBCP, C3P0, BoneCP, Druid, HikariCP等。
- 支持任意实现JDBC规范的数据库。目前支持MySQL,Oracle,SQLServer和PostgreSQL。
主要功能
数据分片
- 分库,分表
- 读写分离
- 分片策略
- 分布式主键
分布式事务
- 标准化事务接口
- XA强一致性事务
- 柔性事务
数据库治理
- 配置动态化
- 编排和治理
- 数据脱敏
- 可视化链路追踪
图中黄色部分表示的是Sharding-JDBC的入口API,采用工厂方法的形式提供。 目前有
- ShardingDataSourceFactory和MasterSlaveDataSourceFactory两个工厂类。
- ShardingDataSourceFactory支持分库分表、读写分离操作
- MasterSlaveDataSourceFactory支持读写分离操作
图中蓝色部分表示的是Sharding-JDBC的配置对象,提供灵活多变的配置方式。
- ShardingRuleConfiguration是分库分表配置的核心和入口,它可以包含多个
- TableRuleConfiguration和MasterSlaveRuleConfiguration。 TableRuleConfiguration封装的是表的分片配置信息,有5种配置形式对应不同的Configuration类型。
- MasterSlaveRuleConfiguration封装的是读写分离配置信息。
图中红色部分表示的是内部对象,由Sharding-JDBC内部使用,应用开发者无需关注。ShardingJDBC通过ShardingRuleConfiguration和MasterSlaveRuleConfiguration生成真正供ShardingDataSource和MasterSlaveDataSource使用的规则对象。ShardingDataSource和MasterSlaveDataSource实现了DataSource接口,是JDBC的完整实现方案。
规则配置
Sharding-JDBC可以通过Java,YAML,Spring命名空间和Spring Boot Starter四种方式配置,开
发者可根据场景选择适合的配置方式。
创建DataSource
通过ShardingDataSourceFactory工厂和规则配置对象获取ShardingDataSource,然后即可通过
DataSource选择使用原生JDBC开发,或者使用JPA, MyBatis等ORM工具。
DataSource dataSource = ShardingDataSourceFactory.createDataSource(dataSourceMap, shardingRuleConfig, props);
数据分片理论知识
核心概念
表概念
- 真实表
数据库中真实存在的物理表。例如b_order0、b_order1 - 逻辑表
在分片之后,同一类表结构的名称(总成)。例如b_order。
- 数据节点
在分片之后,由数据源和数据表组成。例如ds0.b_order1
- 绑定表
指的是分片规则一致的关系表(主表、子表),例如b_order和b_order_item,均按照
order_id分片,则此两个表互为绑定表关系。绑定表之间的多表关联查询不会出现笛卡尔积
关联,可以提升关联查询效率。
b_order:b_order0、b_order1
b_order_item:b_order_item0、b_order_item1 select * from b_order o join b_order_item i on(o.order_id=i.order_id) where o.order_id in (10,11);
如果不配置绑定表关系,采用笛卡尔积关联,会生成4个SQL
select * from b_order0 o join b_order_item0 i on(o.order_id=i.order_id) where o.order_id in (10,11); select * from b_order0 o join b_order_item1 i on(o.order_id=i.order_id) where o.order_id in (10,11); select * from b_order1 o join b_order_item0 i on(o.order_id=i.order_id) where o.order_id in (10,11); select * from b_order1 o join b_order_item1 i on(o.order_id=i.order_id) where o.order_id in (10,11);
如果配置绑定表关系,生成2个SQL
select * from b_order0 o join b_order_item0 i on(o.order_id=i.order_id) where o.order_id in (10,11); select * from b_order1 o join b_order_item1 i on(o.order_id=i.order_id) where o.order_id in (10,11);
- 广播表
在使用中,有些表没必要做分片,例如字典表、省份信息等,因为他们数据量不大,而且这种表可能需要与海量数据的表进行关联查询。广播表会在不同的数据节点上进行存储,存储的表结构和数据完全相同。
分片算法(ShardingAlgorithm)
由于分片算法和业务实现紧密相关,因此并未提供内置分片算法,而是通过分片策略将各种场景提炼出来,提供更高层级的抽象,并提供接口让应用开发者自行实现分片算法。目前提供4种分片算法。
- 精确分片算法PreciseShardingAlgorithm
用于处理使用单一键作为分片键的=与IN进行分片的场景。 - 范围分片算法RangeShardingAlgorithm
用于处理使用单一键作为分片键的BETWEEN AND、>、<、>=、<=进行分片的场景。 - 复合分片算法ComplexKeysShardingAlgorithm
用于处理使用多键作为分片键进行分片的场景,多个分片键的逻辑较复杂,需要应用开发者自行处理其中的复杂度。 - Hint分片算法HintShardingAlgorithm
用于处理使用Hint行分片的场景。对于分片字段非SQL决定,而由其他外置条件决定的场景,可使用SQL Hint灵活的注入分片字段。例:内部系统,按照员工登录主键分库,而数据库中并无此字段。SQL Hint支持通过Java API和SQL注释两种方式使用。
分片策略(ShardingStrategy)
分片策略包含分片键和分片算法,真正可用于分片操作的是分片键 + 分片算法,也就是分片策
略。目前提供5种分片策略。
- 标准分片策略StandardShardingStrategy
只支持单分片键,提供对SQL语句中的=, >, <, >=, <=, IN和BETWEEN AND的分片操作支持。
提供PreciseShardingAlgorithm和Ra