• 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的⻓整型数据。不仅如此它还抽离出分布式主键⽣成器的接口,⽅便我们实现⾃定义的⾃增主键⽣成算法。

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

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

    艾欧尼亚,昂扬不灭,为了更美好的明天而战(#^.^#)
  • 相关阅读:
    Nginx文件下载服务器部署
    Git分支命名规范
    ROS通信介绍
    linux环境设置默认路由的优先级
    Python日志方案
    Python threading Local()函数用法:返回线程局部变量
    Python中websocket的使用示例
    MQTT的Python使用示例
    利用systemback打包个人ISO系统镜像
    Spring Security学习笔记三
  • 原文地址:https://www.cnblogs.com/lovelywcc/p/14851693.html
Copyright © 2020-2023  润新知