文章目录
- 一 基本介绍
- 1.1 概述
- 1.2 ShardingSphere JDBC
- 1.3 ShardingSphere Proxy
- 1.4 ShardingSphere Sidecar
- 1.5 数据库的扩展
- 1.5.1 向上扩展
- 1.5.2 横向扩展
- 1.5.2.1 读写分离
- 1.5.2.2 垂直切分
- 1.5.2.3 水平切分
- 1.6 分库与分表
- 1.6.1 水平分库
- 1.6.2 水平分表
- 1.6.3 垂直分库
- 1.6.4 垂直分表
- 1.7 ShardingSphere JDBC 基本概念
- 1.7.1 逻辑表
- 1.7.2 真实表
- 1.7.3 数据节点
- 1.7.4 分片键
- 1.7.5 分片算法
- 1.7.6 分片策略
- 1.7.7 分布式主键生成策略
- 1.7.8 广播表
- 1.7.9 绑定表
- 1.7.10 路由
- 1.8 扩展带来的问题
一 基本介绍
1.1 概述
前提
官网:Apache SharingSphere
下载地址:https://shardingsphere.apache.org/document/current/cn/downloads/
更新日志:https://github.com/apache/shardingsphere/blob/master/RELEASE-NOTES.md
项目地址:https://shardingsphere.apache.org/
提示:我们需要去关注版本的变化,与修复的问题
产品定位
具体介绍
- Apache ShardingSphere 产品定位为 Database Plus,旨在构建异构数据库上层的标准和生态。
- 它关注如何充分合理地利用数据库的计算和存储能力,而并非实现一个全新的数据库。
- ShardingSphere 站在数据库的上层视角,关注他们之间的协作多于数据库自身。
- 连接、增量 和 可插拔 是 Apache ShardingSphere 的核心概念。
- 连接:通过对数据库协议、SQL 方言以及数据库存储的灵活适配,快速的连接应用与多模式的异构数据库;
- 增量:获取数据库的访问流量,并提供流量重定向(数据分片、读写分离、影子库)、流量变形(数据加密、数据脱敏)、流量鉴权(安全、审计、权限)、流量治理(熔断、限流)以及流量分析(服务质量分析、可观察性)等透明化增量功能;
- 可插拔:项目采用微内核 + 三层可插拔模型,使内核、功能组件以及生态对接完全能够灵活的方式进行插拔式扩展,开发者能够像使用积木一样定制属于自己的独特系统。
- Apache ShardingSphere 由 JDBC、Proxy 和 Sidecar(规划中)这 3 款既能够独立部署,又支持混合部署配合使用的产品组成。 它们均提供标准化的基于数据库作为存储节点的增量功能,可适用于如 Java 同构、异构语言、云原生等各种多样化的应用场景。
- 关系型数据库当今依然占有巨大市场份额,是企业核心系统的基石,未来也难于撼动,我们更加注重在原有基础上提供增量,而非颠覆。
系统架构
1.2 ShardingSphere JDBC
- 定位为轻量级 Java 框架,在 Java 的 JDBC 层提供的额外服务。 它使用客户端直连数据库,以 jar 包形式提供服务,无需额外部署和依赖,可理解为增强版的 JDBC 驱动,完全兼容 JDBC 和各种 ORM 框架。
- 适用于任何基于 JDBC 的 ORM 框架,如:JPA, Hibernate, Mybatis, Spring JDBC Template 或直接使用 JDBC;
- 支持任何第三方的数据库连接池,如:DBCP, C3P0, BoneCP, HikariCP 等;
- 支持任意实现 JDBC 规范的数据库,目前支持 MySQL,PostgreSQL,Oracle,SQLServer 以及任何可使用 JDBC 访问的数据库。
1.3 ShardingSphere Proxy
- 定位为透明化的数据库代理端,提供封装了数据库二进制协议的服务端版本,用于完成对异构语言的支持。 目前提供 MySQL 和 PostgreSQL(兼容 openGauss 等基于 PostgreSQL 的数据库)版本,它可以使用任何兼容 MySQL/PostgreSQL 协议的访问客户端(如:MySQL Command Client, MySQL Workbench, Navicat 等)操作数据,对 DBA 更加友好。
- 向应用程序完全透明,可直接当做 MySQL/PostgreSQL 使用;
- 适用于任何兼容 MySQL/PostgreSQL 协议的的客户端。
1.4 ShardingSphere Sidecar
- 定位为 Kubernetes 的云原生数据库代理,以 Sidecar 的形式代理所有对数据库的访问。 通过无中心、零侵入的方案提供与数据库交互的啮合层,即 Database Mesh,又可称数据库网格。
- Database Mesh 的关注重点在于如何将分布式的数据访问应用与数据库有机串联起来,它更加关注的是交互,是将杂乱无章的应用与数据库之间的交互进行有效地梳理。 使用 Database Mesh,访问数据库的应用和数据库终将形成一个巨大的网格体系,应用和数据库只需在网格体系中对号入座即可,它们都是被啮合层所治理的对象。
对比
1.5 数据库的扩展
- 数据库的扩展可以简单分为两类:向上扩展和横向扩展(水平扩展)。
- 向上扩展是提高硬件,横向扩展是通过副本(读写分离)、垂直切分和水平切分的方式,把不同的数据放在不同的节点(物理部署的MySQL实例)中。
1.5.1 向上扩展
向上扩展,买更好的服务器,这种方式比较简单,一般情况下向上扩展就可以解决问题,但是如果代价太大了(规格越高的硬件需要花费的钱越多),就不可取了。而且向上扩展总有极限的。
1.5.2 横向扩展
横向扩展是通过副本(读写分离)、垂直切分,水平切分的方式,把不同的数据放在不同的节点(物理部署的MySQL实例)中。
1.5.2.1 读写分离
读写分离:给数据库(主数据库)增加一个从数据库,主数据库负责文本的写操作(增,删,改),从数据库负责数据读的操作,如下图所示。也可以一主多从(一个主数据库,多个从数据库),不过需要进行负载均衡。
1.5.2.2 垂直切分
垂直切分:按照功能模块划分数据,举一个例子:一个电商网站,数据库中可能有库存管理的数据,用户管理的数据,订单管理的数据,他们属于不同的功能,可以将一个数据库分成三个数据库,库存管理的数据库,用户管理的数据库,订单管理的数据数据库。
1.5.2.3 水平切分
水平切分:将同一个表中的数据进行分片保存到不同的数据库中。例如:一个用户表,我们可以将用户分片保存的不同的数据库中,可以根据 用户的ID(userID),userID%30的用户放到一个库中,userID%31 放到一个库中,userID%3==2放到一个库中。
1.6 分库与分表
1.6.1 水平分库
![84644bbbbb5741478b69cdfe409eaf26_640_wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1.png](https://img-blog.csdnimg.cn/img_convert/d5b0ff41a7dbfe607ece59a545dc9d60.png
- 以字段为依据,按照一定策略(hash、range等),将一个库中的数据拆分到多个库中。
- 每个库的结构都一样。
- 每个库的数据都不一样,没有交集。
- 所有库的并集是全量数据。
1.6.2 水平分表
- 以字段为依据,按照一定策略(hash、range等),将一个表中的数据拆分到多个表中。
- 每个表的结构都一样。
- 每个表的数据都不一样,没有交集。
- 所有表的并集是全量数据。
1.6.3 垂直分库
- 以表为依据,按照业务归属不同,将不同的表拆分到不同的库中。
- 每个库的结构都不一样。
- 每个库的数据也不一样,没有交集。
- 所有库的并集是全量数据。
1.6.4 垂直分表
- 以字段为依据,按照字段的活跃性,将表中字段拆到不同的表(主表和扩展表)中。
- 每个表的结构都不一。
- 每个表的数据也不一样,一般来说,每个表的字段至少有一列交集,一般是主键,用于关联数据。
- 所有表的并集是全量数据。
1.7 ShardingSphere JDBC 基本概念
1.7.1 逻辑表
- 在对表进行分片后,一张表分成了n个表,比如订单表t_order分成如下三张表:t_order_1,t_order_2,…,t_order_n
- 此时订单表的逻辑表就是t_order,Sharding-JDBC在进行分片规则配置时针对的就是这张逻辑表
1.7.2 真实表
t_ordr_1,t_order_2 称之为 真实表
1.7.3 数据节点
数据分片的最小单元,由数据源名称和表名称组成,比如:d1.t_order_1
1.7.4 分片键
- 用于分片的数据库字段,是将数据库(表)水平拆分的关键字段。例:将订单表中的订单主键的尾数取模分片,则订单主键为分片字段。
- SQL中如果无分片字段,将执行全路由,性能较差。 除了对单分片字段的支持,Sharding- Jdbc也支持根据多个字段进行分片。
1.7.5 分片算法
- 分片算法需要应用方开发者自行实现,可实现的灵 活度非常高。包括:精确分片算法 、范围分片算法 ,复合分片算法 等。例如:where order_id = ? 将采用精确分片算法,where order_id in (?,?,?)将采用精确分片算法,where order_id BETWEEN ? and ? 将采用范围分片算 法,复合分片算法用于分片键有多个复杂情况。
- 内置分片算法参考:https://shardingsphere.apache.org/document/5.1.1/cn/user-manual/shardingsphere-jdbc/builtin-algorithm/sharding/
1.7.6 分片策略
标准分片策略
标准分片策略适用于单分片键,此策略支持 PreciseShardingAlgorithm 和RangeShardingAlgorithm 两个分片算法。
其中 PreciseShardingAlgorithm 是必选的,用于处理 = 和 IN 的分片。RangeShardingAlgorithm 是可选的,用于处理BETWEEN AND, >, <,>=,<= 条件分片,如果不配置RangeShardingAlgorithm,SQL中的条件等将按照全库路由处理。
复合分片策略
复合分片策略,同样支持对 SQL语句中的 =,>, <, >=, <=,IN和 BETWEEN AND 的分片操作。不同的是它支持多分片键,具体分配片细节完全由应用开发者实现。
行表达式分片策略
行表达式分片策略,支持对 SQL语句中的 = 和 IN 的分片操作,但只支持单分片键。这种策略通常用于简单的分片,不需要自定义分片算法,可以直接在配置文件中接着写规则。
t_order_$->{t_order_id % 4} 代表 t_order 对其字段 t_order_id取模,拆分成4张表,而表名分别是t_order_0 到 t_order_3。
Hint分片策略
Hint分片策略,对应上边的Hint分片算法,通过指定分片健而非从 SQL中提取分片健的方式进行分片的策略。
1.7.7 分布式主键生成策略
- 通过在客户端生成自增主键替换以数据库原生自增主键的方式,做到分布式主键无重复。
- Sharding-JDBC 内部支持UUID和Snowflake生成分布式主键
1.7.8 广播表
- 广播表也叫全局表,也就是它会存在于多个库中冗余,避免跨库查询问题。
- 比如省份、字典等一些基础数据,为了避免分库分表后关联表查询这些基础数据存在跨库问题,所以可以把这些数据同步给每一个数据库节点,这个就叫广播表。
1.7.9 绑定表
- 我们有些表的数据是存在逻辑的主外键关系的,比如订单表order_info,存的是汇总的商品数,商品金额;订单明细表order_detail,是每个商品的价格,个数等等。或者叫做从属关系,父表和子表的关系。他们之间会经常有关联查询的操作,如果父表的数据和子表的数据分别存储在不同的数据库,跨库关联查询也比较麻烦。
- 比如order_id=1001的数据在node1,它所有的明细数据也放到node1;order_id=1002的数据在node2,它所有的明细数据都放到node2,这样在关联查询的时候依然是在一个数据库。
1.7.10 路由
应用程序服务器将针对逻辑表编写的 SQL 交给我,我在执行前,要找到 SQL 语句里包含的查询条件(where …)所对应的分片(物理表),然后再针对这些分片进行查询,这个找分片的过程叫做路由。
1.8 扩展带来的问题
- 事务一致性问题:由于分库分表把数据分布在不同库甚至不同服务器,不可避免会带来分布式事务问题。
- 跨节点查询问题:由于原来一张表的数据现在分布在不同数据库,不同表中,在涉及到多表关联,一定要设计好分片策略以及查询条件,否则很可能出现笛卡尔积现象,导致性能更低。
- 跨节点多库进行查询:limit分页、order by排序等问题,就变得比较复杂了。需要先在不同的分片节点中将数据进行排序并返回,然后将不同分片返回的结果集进行汇总和再次排序。
- 不能在采用数据库自增主键,应采用分布式id,保证全局唯一。
- 实际的应用场景中,参数表、数据字典表等都是数据量较小,变动少,而且属于高频联合查询的依赖表。例子中地理区域表也属于此类型。可以将这类表在每个数据库都保存一份,所有对公共表的更新操作都同时发送到所有分库执行。
- 当然ShardingSphere Jdbc来解决这个问题