栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

MySQL(十一):分库分表方案-ShardingSphere

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

MySQL(十一):分库分表方案-ShardingSphere

Sharding-JDBC

Sharding-JDBC定位为轻量级Java框架,在Java的JDBC层提供的额外服务。可理解为增强版的JDBC驱动,完全兼容JDBC和各种ORM 框架的使用

Sharding-JDBC主要功能

1) 数据分片:分库分表、读写分离、分片策略、分布式主键

2) 分布式事务:标准化事务接口、XA强一致性事务、柔性事务

3) 数据库治理:配置动态、服务治理、数据脱敏、链路追踪

核心概念

逻辑表:水平拆分的数据库的相同逻辑和数据结构表的总称

真实表:在分片的数据库中真实存在的物理表。

数据节点:数据分片的最小单元。由数据源名称和数据表组成

绑定表:分片规则一致的主表和子表。(binding-tables)

广播表:也叫公共表,指素有的分片数据源中都存在的表,表结构和表中的数据在每个数据库中都完全一致。例如字典表。(broadcast-tables)

分片键:用于分片的数据库字段,是将数据库(表)进行水平拆分的关键字段。SQL中若没有分片字段,将会执行全路由,性能会很差。

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

分片策略:真正用于进行分片操作的是分片键+分片算法,也就是分片策略。在ShardingJDBC中一般采用基于Groovy表达式的inline分片策略,通过一个包含分片键的算法表达式来制定分片策略,如t_user_$->{u_id%8}标识根据u_id模8,分成8张表,表名称为t_user_0到t_user_7。

分片算法

1) 精确分片算法PreciseShardingAlgorithm

2) 范围分片算法RangeShardingAlgorithm

3) 复合分片算法ComplexKeysShardingAlgorithm

4) Hint分片算法HintShardingAlgorithm

分片策略

1) 标准分片策略StandardShardingStrateg (eq,in,between)

2) 复合分片策略ComplexShardingStrategy (多个字段联合)

3) 行表达式分片策略InlineShardingStrateg (eq)

4) Hint分片策略HintShardingStrategy (与sql无关)

5) 不分片策略NoneShardingStrategy

分片策略配置

1) 数据源分片策略

2) 表分片策略

数据分片流程

1) SQL解析:SQL解析分为词法解析和语法解析。先通过词法解析器将SQL拆分为一个个不可再分的单词。再使 用语法解析器对SQL进行理解,并最终提炼出解析上下文。

2) 查询优化:负责合并和优化分片条件,如OR等。

3) SQL路由:根据解析上下文匹配用户配置的分片策略,并生成路由路径。

4) SQL改写:将SQL改写为在真实数据库中可以正确执行的语句。

5) SQL执行:通过多线程执行器异步执行SQL。

6) 结果归并:将多个执行结果集归并以便于通过统一的JDBC接口输出。

数据分片SQL使用规范

https://shardingsphere.apache.org/document/current/cn/features/sharding/use-norms/sql/

1) 支持路由至单数据节点时,目前MySQL数据库100%全兼容,路由至多数据节点时,全面支持DQL、DML、DDL、DCL、TCL。

2) 路由至多数据节点不支持CASE WHEN、HAVINg、UNIOn (ALL)。

3) 支持分页子查询,但其他子查询有限支持,无论嵌套多少层,只能解析第一层。

4) 由于归并的限制,子查询中包含聚合函数目前无法支持。

5) 不支持包含schema的SQL。

6) 当分片键处于运算表达式或函数中的SQL时,将采用全路由的形式获取结果。

读写分离及架构设计方案

spring.shardingsphere.sharding.master-slave-rules.ds0.masterDataSourceName=m1
spring.shardingsphere.sharding.master-slave-rules.ds0.slaveDataSourceNames[0]=m2

压测影子库 shadow 数据脱敏 encrypt

脱敏配置四部分:数据源配置,加密器配置,脱敏表配置以及查询属性配置

数据源配置:指DataSource的配置信息

加密器配置:指使用什么加密策略进行加解密。目前ShardingSphere内置了两种加解密策略: AES/MD5

脱敏表配置:指定哪个列用于存储密文数据(cipherColumn)、哪个列用于存储明文数据(plainColumn)以及用户想使用哪个列进行SQL编写(logicColumn)

查询属性的配置:当底层数据库表里同时存储了明文数据、密文数据后,该属性开关用于决定是直接查询数据库表里的明文数据进行返回,还是查询密文数据通过Encrypt-JDBC解密后返回。

加密策略解析:
Encryptor:提供encrypt(), decrypt()两种方法对需要脱敏的数据进行加解密。
QueryAssistedEncryptor:即使是相同的数据,如两个用户的密码相同,它们在数据库里存储的脱敏数据也应当是不一样的。

SPI

jdk提供服务实现查找的一个工具类:java.util.ServiceLoader。

Java SPI 的具体约定为:当服务的提供者,提供了服务接口的一种实现之后,在jar包的META-INF/services/目录里同时创建一个以服务接口命名的文件。该文件里就是实现该服务接口的具体实现类。

分布式事务理论CAP和BASE CAP(强一致性)布鲁尔定理。对于共享数据系统,最多只能同时拥有CAP其中的两个 BASE(最终一致性)

基本可用(Basically Available)、软状态( Soft State)、最终一致性( Eventual Consistency)。它的核心思想是即使无法做到强一致性(CAP 就是强一致性),但应用可以采用适合的方式达到最终一致性。

BA指的是基本业务可用性,支持分区失败;

S表示柔性状态,也就是允许短时间内不同步;

E表示最终一致性,数据最终是一致的,但是实时是不一致的。

分布式事务模式2PC和3PC 2PC模式(强一致性)

两阶段提交,就是将事务的提交过程分为两个阶段来进行处理。事务的发起者称协调者,事务的执行者称参与者。

1) 阶段 1:准备阶段 协调者向所有参与者发送事务内容,询问是否可以提交事务,并等待所有参与者答复。 各参与者执行事务操作,但不提交事务,将 undo 和 redo 信息记入事务日志中。 如参与者执行成功,给协调者反馈 yes;如执行失败,给协调者反馈 no。

2) 阶段 2:提交阶段 如果协调者收到了参与者的失败消息或者超时,直接给每个参与者发送回滚(rollback)消息; 否则,发送提交(commit)消息。

2PC 方案存在的问题

1) 性能问题:所有参与者在事务提交阶段处于同步阻塞状态,占用系统资源,容易导致性能瓶颈。

2) 可靠性问题:如果协调者存在单点故障问题,如果协调者出现故障,参与者将一直处于锁定状态。

3) 数据一致性问题:在阶段 2 中,如果发生局部网络问题,一部分事务参与者收到了提交消息,另一部分事务参与者没收到提交消息,那么就导致了节点之间数据的不一致。

3PC模式(强一致性)

两阶段提交的改进版本,引入超时机制,将两阶段的准备阶段拆分为 2 个阶段,插入了一个 preCommit 阶段。

1) 阶段1:canCommit 协调者向参与者发送 commit 请求,参与者如果可以提交就返回 yes 响应,否则返回 no 响应。

2) 阶段2:preCommit 协调者根据阶段 1 canCommit 参与者的反应情况执行预提交事务或中断事务操作。 参与者均反馈 yes:协调者向所有参与者发出 preCommit 请求,参与者收到 preCommit 请求后,执行事务操作,但不提交;将 undo 和 redo 信息记入事务日志 中;各参与者向协调者反馈 ack 响应或 no 响应,并等待最终指令。 任何一个参与者反馈 no或等待超时:协调者向所有参与者发出 abort 请求,无论收到协调者发出的 abort 请求,或者在等待协调者请求过程中出现超时,参与者均会中断事务。

3) 阶段3:do Commit 该阶段进行真正的事务提交,根据阶段 2 preCommit反馈的结果完成事务提交或中断操作。

事务demo
    @Transactional
    @ShardingTransactionType(TransactionType.BASE) //LOCAL,XA,BASE
    public void insertProductTransaction() {
    }
properties demo
spring.shardingsphere.datasource.names=m1,m2

spring.shardingsphere.datasource.m1.type=com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.m1.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.m1.url=jdbc:mysql://xxxxxxxx:3316/shardingdb1
spring.shardingsphere.datasource.m1.username=root
spring.shardingsphere.datasource.m1.password=xxxxxxxx

spring.shardingsphere.datasource.m2.type=com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.m2.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.m2.url=jdbc:mysql://xxxxxxxx:3316/shardingdb2
spring.shardingsphere.datasource.m2.username=root
spring.shardingsphere.datasource.m2.password=xxxxxxxx

#spring.shardingsphere.sharding.master-slave-rules.ds0.masterDataSourceName=m1
#spring.shardingsphere.sharding.master-slave-rules.ds0.slaveDataSourceNames[0]=m2

#spring.shardingsphere.sharding.tables.t_product.actualDataNodes=ds0.t_product

spring.shardingsphere.sharding.tables.product.actualDataNodes=m$->{1..2}.product_$->{1..2}

spring.shardingsphere.sharding.tables.product.key-generator.column=pid
spring.shardingsphere.sharding.tables.product.key-generator.type=SNOWFLAKE
spring.shardingsphere.sharding.tables.product.key-generator.props.worker.id=1

spring.shardingsphere.sharding.tables.inventory.actualDataNodes=m$->{1..2}.inventory_$->{1..2}

spring.shardingsphere.sharding.tables.inventory.key-generator.column=iid
spring.shardingsphere.sharding.tables.inventory.key-generator.type=SNOWFLAKE
spring.shardingsphere.sharding.tables.inventory.key-generator.props.worker.id=1

spring.shardingsphere.sharding.tables.product.database-strategy.inline.sharding-column=pid
spring.shardingsphere.sharding.tables.product.database-strategy.inline.algorithm-expression=m$->{pid%2+1}

spring.shardingsphere.sharding.tables.product.table-strategy.inline.sharding-column=pid
spring.shardingsphere.sharding.tables.product.table-strategy.inline.algorithm-expression=product_$->{((pid+1)%4).intdiv(2)+1}

spring.shardingsphere.sharding.tables.category.actualDataNodes=m$->{1..2}.category_$->{1..2}
spring.shardingsphere.sharding.tables.category.key-generator.column=cid
spring.shardingsphere.sharding.tables.category.key-generator.type=SNOWFLAKE
spring.shardingsphere.sharding.tables.category.key-generator.props.worker.id=1

spring.shardingsphere.sharding.broadcast-tables[0]=category

#spring.shardingsphere.sharding.binding-tables[0]=product,inventory

spring.shardingsphere.props.sql.show=true
standard.....
complex.....
hint.....
Sharding-JDBC 源码流程

Sharding-Proxy


下载: https://shardingsphere.apache.org/document/current/cn/downloads/

  1. conf/server.yaml、conf/config-sharding.yaml (config-encrypt.yaml config-master_slave.yaml config-shadow.yaml logback.xml)
  2. If you want to connect to MySQL, you should manually copy MySQL driver to lib directory.
  3. ./bin/start.sh 3316
  4. tail -f logs/stdout.log
  5. mysql -h0.0.0.0 -P3316 -usharding -psharding
  6. show databases;
  7. use sharding_db
  8. show tables;

配置:ConfigurationPropertyKey.java

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/821034.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号