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

Posted lovelywcc

tags:

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

在开始 Sharding-JDBC分库分表具体实战之前,我们有必要先了解分库分表的一些核心概念,主要包括:

  • SQL核心概念
  • 分片核心概念
  • 配置核心概念
  • 行表达式
  • 分布式主键
  • 强制分片路由

image
在进行基础的概念讲解前,我们先来看个图,用的processon画的,刚学,画的不好看哈哈,意思能表达清楚就行哈一会。

一般我们在提到分库分表的时候,大多是以水平切分模式(水平分库、分表)为基础来说的,数据分片将原本一张数据量较大的表 t_order 拆分生成数个表结构完全一致的小数据量表 t_order_0、t_order_1、···、t_order_n,每张表只存储原大表中的一部分数据,当执行一条SQL(增删改查)时会通过分库策略、分片策略 将数据分散到不同的数据库、表内。

1.sql

1.1 逻辑表

水平拆分的数据库(表)的相同逻辑和数据结构表的总称。比如我们将订单表t_order 拆分成 t_order_0 ··· t_order_9 等 10张表。此时我们会发现分库分表以后数据库中已不在有 t_order 这张表,取而代之的是 t_order_n,但我们在代码中写 SQL依然按 t_order 来写。此时 t_order 就是这些拆分表的逻辑表。

1.2 真实表

在分片的数据库中真实存在的物理表。即上图示例中的 t_order_1 到 t_order_2。

1.3 数据节点

数据节点是分库分表中一个不可再分的最小数据单元(表),它由数据源名称和数据表组成,例如上图中 order_db_1.t_order_0、order_db_2.t_order_1 就表示一个数据节点。

1.4 绑定表

绑定表:那些分片规则一致的主表和子表。比如:t_order 订单表和 t_order_item 订单服务项目表,都是按 order_id 字段分片,因此两张表互为绑定表关系。

那绑定表存在的意义是啥呢?

通常在我们的业务中都会使用 t_order 和 t_order_item 等表进行多表联合查询,但由于分库分表以后这些表被拆分成N多个子表。如果不配置绑定表关系,会出现笛卡尔积关联查询,将产生如下四条SQL。

SELECT * FROM t_order_0 o JOIN t_order_item_0 i ON o.order_id=i.order_id 
SELECT * FROM t_order_0 o JOIN t_order_item_1 i ON o.order_id=i.order_id 
SELECT * FROM t_order_1 o JOIN t_order_item_0 i ON o.order_id=i.order_id 
SELECT * FROM t_order_1 o JOIN t_order_item_1 i ON o.order_id=i.order_id

image
而配置绑定表关系后再进行关联查询时,只要对应表分片规则一致产生的数据就会落到同一个库中,那么只需 t_order_0和 t_order_item_0 表关联即可。

SELECT * FROM t_order_0 o JOIN t_order_item_0 i ON o.order_id=i.order_id
SELECT * FROM t_order_1 o JOIN t_order_item_1 i ON o.order_id=i.order_id

image

注意:在关联查询时 t_order 它作为整个联合查询的主表。所有相关的路由计算都只使用主表的策略,t_order_item 表的分片相关的计算也会使用 t_order 的条件,所以要保证绑定表之间的分片键要完全相同,当保证这些一样之后,根据sql去查询时会统一的路由到0表或者1表,自然就没有笛卡尔积问题了。

1.5 广播表

指所有的分片数据源中都存在的表,表结构和表中的数据在每个数据库中均完全一致。适用于数据量不大且需要与海量数据的表进行关联查询的场景,例如:字典表,某个表一旦被配置为广播表,只要修改某个数据库的广播表,所有数据源中广播表的数据都会跟着同步

1.6 单表

指所有的分片数据源中只存在唯一一张的表。适用于数据量不大且不需要做任何分片操作的场景。

2.分片

2.1 分片键

用于分片的数据库字段,是将数据库(表)水平拆分的关键字段。例:将订单表中的订单主键的尾数取模分片,则订单主键为分片字段。 SQL 中如果无分片字段,将执行全路由(去查询所有的真实表),性能较差。 除了对单分片字段的支持,Apache ShardingSphere 也支持根据多个字段进行分片。
image
这样以来同一个订单的相关数据就会存在同一个数据库表中,大幅提升数据检索的性能

2.2 分片算法

通过分片算法将数据分片,支持通过 =、>=、<=、>、<、BETWEEN 和 IN 分片。 分片算法需要应用方开发者自行实现,可实现的灵活度非常高。

目前提供 3 种分片算法。 由于分片算法和业务实现紧密相关,因此并未提供内置分片算法,而是通过分片策略将各种场景提炼出来,提供更高层级的抽象,并提供接口让应用开发者自行实现分片算法。

  • 标准分片算法
    对应 StandardShardingAlgorithm,用于处理使用单一键作为分片键的 =、IN、BETWEEN AND、>、<、>=、<= 进行分片的场景。需要配合 StandardShardingStrategy 使用
  • 复合分片算法
    对应 ComplexKeysShardingAlgorithm,用于处理使用多键作为分片键进行分片的场景,包含多个分片键的逻辑较复杂,需要应用开发者自行处理其中的复杂度。需要配合 ComplexShardingStrategy 使用。
  • Hint分片算法
    对应 HintShardingAlgorithm,用于处理使用 Hint 行分片的场景。需要配合 HintShardingStrategy 使用

2.3 分片策略

分片策略是一种抽象的概念,实际分片操作的是由分片算法和分片健来完成的。即真正可用于分片操作的是分片键 + 分片算法,也就是分片策略。目前提供 4 种分片策略。

  • 标准分片策略
    对应 StandardShardingStrategy。提供对 SQL 语句中的 =, >, <, >=, <=, IN 和 BETWEEN AND 的分片操作支持。 StandardShardingStrategy 只支持单分片键,提供 PreciseShardingAlgorithm 和 RangeShardingAlgorithm 两个分片算法。 PreciseShardingAlgorithm 是必选的,用于处理 = 和 IN 的分片。 RangeShardingAlgorithm 是可选的,用于处理 BETWEEN AND, >, <, >=, <= 分片,如果不配置 RangeShardingAlgorithm,SQL 中的 BETWEEN AND 将按照全库路由处理。
  • 复合分片策略
    对应 ComplexShardingStrategy。复合分片策略。提供对 SQL 语句中的 =, >, <, >=, <=, IN 和 BETWEEN AND 的分片操作支持。 ComplexShardingStrategy 支持多分片键,由于多分片键之间的关系复杂,因此并未进行过多的封装,而是直接将分片键值组合以及分片操作符透传至分片算法,完全由应用开发者实现,提供最大的灵活度。
  • Hint分片策略
    对应 HintShardingStrategy。通过 Hint 指定分片值而非从 SQL 中提取分片值的方式进行分片的策略。也就是说,这个分片的规则不是由执行的sql决定的,并不会根据sql去路由到哪个库或者表,我理解的是,我们可以在某些场景下,指定这种规则,而不是根据sql那种方式。
  • 不分片策略
    对应 NoneShardingStrategy。不分片的策略。

从执行 SQL 的角度来看,分库分表可以看作是一种路由机制,把 SQL 语句路由到我们期望的数据库或数据表中并获取数据,分片算法可以理解成一种路由规则。

2.4 SQL Hint

这个官网对此解析的很清楚
对于分片字段非 SQL 决定,而由其他外置条件决定的场景,可使用 SQL Hint 灵活的注入分片字段。 例:内部系统,按照员工登录主键分库,而数据库中并无此字段。SQL Hint 支持通过 Java API 和 SQL 注释(待实现)两种方式使用。

  • 实现动机
    通过解析 SQL 语句提取分片键列与值并进行分片是 Apache ShardingSphere 对 SQL 零侵入的实现方式。若 SQL 语句中没有分片条件,则无法进行分片,需要全路由。在一些应用场景中,分片条件并不存在于 SQL,而存在于外部业务逻辑。因此需要提供一种通过外部指定分片结果的方式,在 Apache ShardingSphere 中叫做 Hint。
  • 实现机制
    Apache ShardingSphere 使用 ThreadLocal 管理分片键值。可以通过编程的方式向 HintManager 中添加分片条件,该分片条件仅在当前线程内生效。

除了通过编程的方式使用强制分片路由,Apache ShardingSphere 还计划通过 SQL 中的特殊注释的方式引用 Hint,使开发者可以采用更加透明的方式使用该功能。指定了强制分片路由的 SQL 将会无视原有的分片逻辑,直接路由至指定的真实数据节点。

3.分布式主键

数据分⽚后,不同数据节点⽣成全局唯⼀主键是⾮常棘⼿的问题,同⼀个逻辑表(t_order)内的不同真实表(t_order_n)之间的⾃增键由于⽆法互相感知而产⽣重复主键。

尽管可通过设置⾃增主键初始值和步⻓的⽅式避免ID碰撞,但这样会使维护成本加大,缺乏完整性和可扩展性。如果后去需要增加分片表的数量,要逐一修改分片表的步长,运维成本非常高,所以不建议这种方式。
类似这种哈,简单示意图
image
实现分布式主键⽣成器的方式很多,具体可以百度,网上有很多

为了让上手更加简单,ApacheShardingSphere 内置了UUID、SNOWFLAKE 两种分布式主键⽣成器,默认使⽤雪花算法(snowflake)⽣成64bit的⻓整型数据。不仅如此它还抽离出分布式主键⽣成器的接口,⽅便我们实现⾃定义的⾃增主键⽣成算法。

至于算法具体怎么得出来得不同的主键值,各个大厂也有自己的实现,大家自行查看即可。

大概先知道这么多吧,基本够用了,后面具体研究深入使用,再去查找官网,后面我们进行一个简单的快速入门搭建。

以上是关于Apache ShardingSphere ---;2.数据分片的核心概念的主要内容,如果未能解决你的问题,请参考以下文章

Apache首个分布式数据库中间件项目ShardingSphere进入孵化器

京东数科主导的首个Apache基金会项目ShardingSphere进入孵化器

Apache ShardingSphere集成

暑期 2021 参与社区——Apache ShardingSphere

深度剖析Apache Shardingsphere对分布式事务的支持

记一次给Apache顶级项目ShardingSphere提交Bug的经历