Sharding-JDBC核心概念解析

Posted 踩踩踩从踩

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Sharding-JDBC核心概念解析相关的知识,希望对你有一定的参考价值。

前言

本篇文章会从Sharding-JDBC用途、使用场景、架构,Sharding-JDBC配置使用,Sharding-JDBC分库分表实战,Sharding-JDBC事务应用与数据治理等几个方面去解析Sharding-JDBC ;对于它来说和mycat的最大区别还是作为客户端数据中间件做为解决海量数据存储的方式。

官网:ShardingSphere (apache.org)

Sharding-JDBC用途、使用场景、架构

说到 Sharding-JDBC  一定要说到ShardingSphere。

ShardingSphere是一套开源的分布式数据库中间件解决方案组成的生态圈,它由Sharding-JDBC、 Sharding-Proxy和Sharding-Sidecar(计划中)这3款相互独立的产品组成。 他们均提供标准化 的数据分片、分布式事务和数据库治理功能,可适用于如Java同构、异构语言、容器、云原生等 各种多样化的应用场景。

Apache ShardingSphere 旨在充分合理地在分布式的场景下利用关系型数据库的计算和存储能力,而并非实现一个全新的关系型数据库。 关系型数据库当今依然占有巨大市场份额,是企业核心系统的基石,未来也难于撼动,我们更加注重在原有基础上提供增量,而非颠覆。

Apache ShardingSphere 5.x 版本开始致力于可插拔架构,项目的功能组件能够灵活的以可插拔的方式进行扩展。 目前,数据分片、读写分离、数据加密、影子库压测等功能,以及 mysql、PostgreSQL、SQLServer、Oracle 等 SQL 与协议的支持,均通过插件的方式织入项目。 开发者能够像使用积木一样定制属于自己的独特系统。Apache ShardingSphere 目前已提供数十个 SPI 作为系统的扩展点,仍在不断增加中。

作为 ShardingSphere的一部分 Sharding-JDBC  ,有着对jdbc层提供额外服务的功能。

 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。

Sharding-Proxy 

 定位为透明化的数据库代理端,提供封装了数据库二进制协议的服务端版本,用于完成对异构语言的支持。 目前提供 MySQL 和 PostgreSQL(兼容 openGauss 等基于 PostgreSQL 的数据库)版本,它可以使用任何兼容 MySQL/PostgreSQL 协议的访问客户端(如:MySQL Command Client, MySQL Workbench, Navicat 等)操作数据,对 DBA 更加友好。

  • 向应用程序完全透明,可直接当做 MySQL/PostgreSQL 使用;
  • 适用于任何兼容 MySQL/PostgreSQL 协议的的客户端。

生态链的形式。

对比起来

混合架构

Sharding-JDBC采用无中心化架构,适用于Java开发的高性能的轻量级OLTP应用;Sharding-Proxy提供静态入口以及异构语言的支持,适用于OLAP应用以及对分片数据库进行管理和运维的场景。
ShardingSphere是多接入端共同组成的生态圈。通过混合使用Sharding-JDBC和
Sharding-Proxy,并采用同一注册中心统一配置分片策略,能够灵活的搭建适用于各种场景的应用系统,架构师可以更加自由的调整适合于当前业务的最佳系统架构

 

 

功能清单

数据分片:
  • 分库 & 分表
  •  读写分离
  •  分布式主键

 分布式事务(doing):

  • XA强一致事务
  • 柔性事务
数据库治理:
  • 配置动态化
  • 熔断 & 禁用
  • 调用链路追踪
  •  弹性伸缩 (Planning)

数据分片内核工作原理

ShardingSphere的3个产品的数据分片主要流程是完全一致的
核心由SQL解析 => 执行器优化 => SQL路由 => SQL改写 => SQL执行 => 结果归并的流程组成

 版本规划

 Sharding-JDBC配置使用

Sharding-JDBC使用客户端直连数据库,以jar包形式提供服务,无需额外部署和依赖,可理解为增强版的JDBC驱动,完全兼容JDBC和各种ORM框架。

不使用spring的方式

引入Maven依赖

<dependency> 
    <groupId>org.apache.shardingsphere</groupId> 
    <artifactId>sharding-jdbc-core</artifactId> 
    <version>${sharding-sphere.version}</version> 
</dependency>
基于 Java 编码的规则配置
Sharding-JDBC 的分库分表通过规则配置描述,以下例子是根据 user_id 取模分库 , 且根据
order_id 取模分表的两库两表的配置。

 

基于 Yaml 的规则配置
或通过 Yaml 方式配置,与以上配置等价:

 

使用原生JDBC

通过 ShardingDataSourceFactory 或者 YamlShardingDataSourceFactory 工厂和规则配置对象
获取 ShardingDataSource ShardingDataSource 实现自 JDBC 的标准接口 DataSource 。然后
可通过 DataSource 选择使用原生 JDBC 开发,或者使用 JPA, MyBatis ORM 工具。 以 JDBC 原生
实现为例:

 

 使用Spring

引入 Maven 依赖
<!-- for spring boot -->
 <dependency> 
    <groupId>io.shardingsphere</groupId> 
    <artifactId>sharding-jdbc-spring-boot-starter</artifactId> 
    <version>${sharding-sphere.version}</version> 
</dependency> 
<!-- for spring namespace --> 
<dependency> 
    <groupId>io.shardingsphere</groupId> 
    <artifactId>sharding-jdbc-spring-namespace</artifactId> 
    <version>${sharding-sphere.version}</version>
 </dependency>
基于 Spring boot 的规则配置
sharding.jdbc.datasource.names=ds0,ds1 
sharding.jdbc.datasource.ds0.type=org.apache.commons.dbcp2.BasicDataSource 
sharding.jdbc.datasource.ds0.driver-class-name=com.mysql.jdbc.Driver 
sharding.jdbc.datasource.ds0.url=jdbc:mysql://localhost:3306/ds0 
sharding.jdbc.datasource.ds0.username=root sharding.jdbc.datasource.ds0.password= 
sharding.jdbc.datasource.ds1.type=org.apache.commons.dbcp2.BasicDataSource 
sharding.jdbc.datasource.ds1.driver-class-name=com.mysql.jdbc.Driver 
sharding.jdbc.datasource.ds1.url=jdbc:mysql://localhost:3306/ds1 
sharding.jdbc.datasource.ds1.username=root sharding.jdbc.datasource.ds1.password=
sharding.jdbc.config.sharding.default-database-strategy.inline.sharding- column=user_id 
sharding.jdbc.config.sharding.default-database-strategy.inline.algorithm- expression=ds$->
{user_id % 2} sharding.jdbc.config.sharding.tables.t_order.actual-data-nodes=ds$-> 
{0..1}.t_order$->{0..1} sharding.jdbc.config.sharding.tables.t_order.table- 
strategy.inline.sharding-column=order_id 
sharding.jdbc.config.sharding.tables.t_order.table- strategy.inline.algorithm-
expression=t_order$->{order_id % 2} 
sharding.jdbc.config.sharding.tables.t_order_item.actual-data-nodes=ds$-> 
{0..1}.t_order_item$->{0..1} sharding.jdbc.config.sharding.tables.t_order_item.table- 
strategy.inline.sharding-column=order_id 
sharding.jdbc.config.sharding.tables.t_order_item.table- strategy.inline.algorithm-
expression=t_order_item$->{order_id % 2}
基于 Spring 命名空间的规则配置

Spring中使用DataSource

直接通过注入的方式即可使用 DataSource ,或者将 DataSource 配置在 JPA Hibernate
MyBatis 中使用。

 

@Resource
 private DataSource dataSource;

数据源配置

yaml 格式

spring boot 配置

 数据源配置说明

注意,可配置属性说明 ,下面的。一些数据配置

Sharding-JDBC分库分表

进行垂直和水平拆分开, 

逻辑表
水平拆分的数据库(表)的相同逻辑和数据结构表的总称。例:订单数据根据主键%2拆分为2张表,分别是t_order0、t_order1,他们的逻辑表名为t_order。

数据节点

数据分片的最小单元。由数据源名称和数据表组成,例: ds0.t_order0

 真实表

在分片的数据库中真实存在的物理表。即上个示例中的t_order0到t_order1

数据节点

tables:
 t_order: 
actualDataNodes: ds$->{0..1}.t_order$->{0..1}数据节点
数据分片的最小单元。由数据源名称和数据表组成,例:ds0.t_order0。
数据节点分布说明
均匀分布:数据源能力均衡

 

db0.t_order0,db0.t_order1,db1.t_order0,db1.t_order1

db$->{0..1}.t_order$->{0..1}
自定义分布:数据源能力不均

 

db0.t_order0,db0.t_order1,db1.t_order2,
db1.t_order3,db1.t_order4

db0.t_order$->{0..1},db1.t_order$->{2..4}

 分片策略

数据源分片、表分片仅是两个不同维度的分片,它们能用的分片策略规则是一样的。
Sharding-JDBC中提供了常用的分片策略实现。分片策略由两部分构成:
  • 分片键
  •  分片算法

JDBC提供的5种分片策略

none 不分片策略
对应NoneShardingStrategy ,不分片策略 ,SQL会被发给所有节点去执行,这个规则没有子项目可以配置。
inline 行表达式分片策略
对应InlineShardingStrategy。使用Groovy的表达式,提供对SQL语句中的=和IN的分片操作支持,只支持单分片键。对于简单的分片算法,可以通过简单的配置使用,从而避免繁琐的Java代码开发,如: t_user_$->{u_id % 8} 表示t_user表根据u_id模8,而分成8张表,表名称为t_user_0到t_user_7。
databaseStrategy: 
    inline:
        shardingColumn: user_id
        algorithmInlineExpression: ds${user_id % 2}
行表达式语法
  • ${begin..end}表示范围区间
  • ${[unit1, unit2, unit_x]}表示枚举值
  •  行表达式中如果出现连续多个${ expression }或$->{ expression }表达式,整个表达式最终的结果将会根据每个子表达式的结果进行笛卡尔组合。

Standard 标准分片策略
  • 对应StandardShardingStrategy。提供对SQL语句中的=, IN和BETWEEN AND的分片操作支持。
  • StandardShardingStrategy只支持单分片键,提供PreciseShardingAlgorithm和RangeShardingAlgorithm 两个分片算法。
  •  PreciseShardingAlgorithm是必选的,用于处理=和IN的分片。
  • RangeShardingAlgorithm是可选的,用于处理BETWEEN AND分片,如果不配置RangeShardingAlgorithm,SQL中的BETWEEN AND将按照全库路由处理。

 complex 复合分片策略

  • 对应ComplexShardingStrategy。复合分片策略提供对SQL语句中的=, IN和BETWEEN AND的分片操作支持。
  •  ComplexShardingStrategy支持多分片键,由于多分片键之间的关系复杂,因此并未进行过多的封装,而是直接将分片键值组合以及分片操作符透传至分片算法,完全由应用开发者实现,提供最大的灵活度。
hint分片策略
  • 对应HintShardingStrategy。通过Hint而非SQL解析的方式分片的策略。
  • 对于分片字段非SQL决定,而由其他外置条件决定的场景,可使用SQL Hint灵活的注入分片字段。例:内部系统,按照员工登录主键分库,而数据库中并无此字段。SQL Hint支持通过Java API和SQL注释(待实现)两种方式使用。

 

JDBC配置默认数据源、分片策略 

可配置默认的数据源、数据源分片策略、表分片策略

 

分布式主键

ShardingSphere提供灵活的配置分布式主键生成策略方式。 在分片规则配置模块可配置每个表的主键生成策略,默认使用雪花算法(snowflake)生成64bit的长整型数据。
当前提供了 SNOWFLAKE、UUID 两种可用方式。

 配置说明

defaultkeyGenerator: #默认的主键生成算法 如果没有设置,默认
为SNOWFLAKE算法
column: # 自增键对应的列名称
type: #自增键的类型,主要用于调用内置的主键生成算法有三个可 用值:SNOWFLAKE(时间戳+worker id+自增
id),UUID(java.util.UUID类生成的随机UUID),LEAF,其中S
nowflake算法与UUID算法已经实现,LEAF目前(2018-01-14)尚 未实现
props:# 定制算法需要设置的参数,比如SNOWFLAKE算法的worker.id
与max.tolerate.time.difference.milliseconds

 

绑定表

指分片规则一致的主表和子表。例如:t_order表和t_order_item表,均按照order_id分片,则此两张表互为绑定表关系。绑定表之间的多表关联查询不会出现笛卡尔积关联,关联查询效率将大大提升。
如果SQL为
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);
在不配置绑定表关系时 假设分片键order_id将数值10路由至第0片,将数值11路由至第1片,那
么路由后的SQL应该为4条,它们呈现为笛卡尔积:

 在配置绑定表关系后,路由的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);
其中t_order在FROM的最左侧,ShardingSphere将会以它作为整个绑定表的主表。 所有路由计算将会只使用主表的策略,
那么t_order_item表的分片计算将会使用t_order的条件。故绑定表之间的分区键要完全相同。

广播表

指所有的分片数据源中都存在的表,表结构和表中的数据在每个数据库中均完全一致。适用于数
据量不大且需要与海量数据的表进行关联查询的场景,例如:字典表。
shardingRule:
broadcastTables:
- t_config

JDBC事务应用与数据治理

Spring-boot-starter 方式

<dependency>
     <groupId>io.shardingsphere</groupId>
     <artifactId>sharding-transaction-spring-boot-starter</artifactId>
     <version>${sharding-sphere.version}</version>
</dependency>

业务代码中应用

@ShardingTransactionType(TransactionType.LOCAL)
@Transactional
@ShardingTransactionType(TransactionType.XA)
@Transactional

分布式事务应用

Atomikos参数配置
ShardingSphere默认的XA事务管理器为Atomikos。 可以通过在项目的classpath中添加jta.properties 来定制化Atomikos配置项。 具体的配置规则请参考Atomikos的官方文档。
实现动机
  • 配置集中心化:越来越多的运行时实例,使得散落的配置难于管理,配置不同步导致的问题分严重。将配置集中于配置中心,可以更加有效进行管理。
  • 配置动态化:配置修改后的分发,是配置中心可以提供的另一个重要能力。它可支持数据源、 表与分片及读写分离策略的动态切换。

以上是关于Sharding-JDBC核心概念解析的主要内容,如果未能解决你的问题,请参考以下文章

轻量级数据库中间件利器Sharding-JDBC深度解析(有彩蛋)

Myqsql使用Sharding-JDBC分表分库和读写分离

5W 字详解分库分表之 Sharding-JDBC 中间件

分库分表之Sharding-JDBC

Apache ShardingSphere ---;2.数据分片的核心概念

源码解析Sharding-Jdbc模块分析