ShardingSphere-JDBC学习笔记

引言

开源产品的小故事

Sharding-JDBC是2015年开源的,早期的定位就是一个分布式数据库的中间件,而在它之前有一个MyCat的产品。MyCat也是从阿里开源出来的,作为分库分表的代名词火了很长一段时间,而MyCat早年的目标就是想进入apache(从命名也可以看出,希望像Tomcat一样),但是很可惜最后由于社区运营不是很成熟没有达成。但是现在它的这个愿望早就已经被ShardingSphere达成了,ShardingSphere现在就是apache的顶级开源项目。

ShardingSphere版本演进

从15年开始作为一个小的中间件,发展至今已成为了一个庞然大物。

当不使用分片键时,ShardingSphere是怎么执行的呢?

在之前4.x版本下,这种情况会拆分成多个SQL(每个真实表分片对应一个sql),查询多次。新版本下,会将每一个真实库里的语句通过UNION合并成一个大SQL,一起进行查询。

如果需要对一个真实库进行多个SQL查询,那么就需要通过多线程进行并发查询,这种情况下,如果要进行后续的结果归并,比如sum、max这样的结果归并,那就只能将所有的结果都合并到一个大内存,再进行归并。这种方式称为内存归并消耗内存,多线程

如果合并成了一个大的SQL,对一个真实库只要进行一次SQL查询,这样就可以通过一个线程进行查询。在进行结果归并时,就可以拿一条数据归并一次。这种方式称为流式归并极大的节约内存

另外,在使用in进行查询时,有可能计算出属于多个不同的分片。在4.x版本当中,如果出现了这种情况,由于ShardingSphere无法确定in算出来的分片有多少个,所以遇到这种情况,他就不再去计算in中所有的分片结果了,直接改为全路由分片。这样计算比较简单,但是查询的效率肯定不好。而在新版本下,能够准确的计算出分片

补充:ShardingSphere实现分库分表的核心概念

  1. 虚拟库: ShardingSphere的核心就是提供一个具备分库分表功能的虚拟库,他是一个ShardingSphereDatasource实例。应用程序只需要像操作单数据源一样访问这个ShardingSphereDatasource即可。

  2. 真实库: 实际保存数据的数据库。这些数据库都被包含在ShardingSphereDatasource实例当中,由ShardingSphere决定未来需要使用哪个真实库。

  3. 逻辑表: 应用程序直接操作的逻辑表。

  4. 真实表: 实际保存数据的表。这些真实表与逻辑表表名不需要一致,但是需要有相同的表结构,可以分布在不同的真实库中。应用可以维护一个逻辑表与真实表的对应关系,所有的真实表默认也会映射成为ShardingSphere的虚拟表。

  5. 分布式主键生成算法: 给逻辑表生成唯一主键。由于逻辑表的数据是分布在多个真实表当中的,所以单表的索引就无法保证逻辑表的ID唯一性。ShardingSphere集成了几种常见的基于单机生成的分布式主键生成器。比如SNOWFLAKE,COSID_SNOWFLAKE雪花算法可以生成单调递增的long类型的数字主键,还有UUID,NANOID可以生成字符串类型的主键。当然,ShardingSphere也支持应用自行扩展主键生成算法。比如基于Redis,Zookeeper等第三方服务,自行生成主键。

  6. 分片策略: 表示逻辑表要如何分配到真实库和真实表当中,分为分库策略和分表策略两个部分。分片策略由分片键和分片算法组成。分片键是进行数据水平拆分的关键字段。如果没有分片键,ShardingSphere将只能进行全路由,SQL执行的性能会非常差。分片算法则表示根据分片键如何寻找对应的真实库和真实表。简单的分片策略可以使用Groovy表达式直接配置,当然,ShardingSphere也支持自行扩展更为复杂的分片算法。

ShardingSphere-JDBC其他策略

广播表

广播表认为在所有的片里面是一致的,不会进行转发,即使配置了分片规则也不会生效

使用场景:在所有分片都需要的表,比如字典表,在所有库上数据保持一致

参考配置:

# 打印SQL,spring.shardingsphere.props.sql-show,不同版本的参数可能不同,中间是-
spring.shardingsphere.props.sql.show=true
spring.main.allow-bean-definition-overriding=true
spring.shardingsphere.datasource.names=m0,m1spring.shardingsphere.datasource.m0.type=com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.m0.driver-class-name=com.mysql.cj.jdbc.Driver
spring.shardingsphere.datasource.m0.url=jdbc:mysql://localhost:3306/coursedb?serverTimezone=UTC
spring.shardingsphere.datasource.m0.username=root
spring.shardingsphere.datasource.m0.password=123666spring.shardingsphere.datasource.m1.type=com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.m1.driver-class-name=com.mysql.cj.jdbc.Driver
spring.shardingsphere.datasource.m1.url=jdbc:mysql://localhost:3306/coursedb2?serverTimezone=UTC
spring.shardingsphere.datasource.m1.username=root
spring.shardingsphere.datasource.m1.password=123666spring.shardingsphere.sharding.tables.dict.key-generator.column=dictId
spring.shardingsphere.sharding.tables.dict.key-generator.type=SNOWFLAKE
spring.shardingsphere.sharding.tables.dict.key-generator.props.worker.id=1
spring.shardingsphere.sharding.tables.dict.actual-data-nodes=m$->{0..1}.dict_$->{1..2}spring.shardingsphere.sharding.broadcast-tables=dict

测试代码:

@Test
public void dict()
{Dict dict = new Dict();dict.setDictkey("1");dict.setDictval("true");dictMapper.insert(dict);Dict dict2 = new Dict();dict2.setDictkey("2");dict2.setDictval("false");dictMapper.insert(dict2);
}@TableName("dict")
public class Dict {private Long dictid;private String dictkey;private String dictval;@Overridepublic String toString() {return "Dict{" +"dictId=" + dictid +", dictkey='" + dictkey + '\'' +", dictval='" + dictval + '\'' +'}';}public Long getDictid() {return dictid;}public void setDictid(Long dictid) {this.dictid = dictid;}public String getDictkey() {return dictkey;}public void setDictkey(String dictkey) {this.dictkey = dictkey;}public String getDictval() {return dictval;}public void setDictval(String dictval) {this.dictval = dictval;}
}

测试结果:两个库的Dict表都增加了两条数据

注意:这里插入的是dict表,而不是dict_1和dict_2

绑定表

参考配置:

spring.shardingsphere.props.sql.show=truespring.shardingsphere.datasource.names=m0,m1spring.shardingsphere.datasource.m0.type=com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.m0.driver-class-name=com.mysql.cj.jdbc.Driver
spring.shardingsphere.datasource.m0.url=jdbc:mysql://localhost:3306/coursedb?serverTimezone=UTC
spring.shardingsphere.datasource.m0.username=root
spring.shardingsphere.datasource.m0.password=123666spring.shardingsphere.datasource.m1.type=com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.m1.driver-class-name=com.mysql.cj.jdbc.Driver
spring.shardingsphere.datasource.m1.url=jdbc:mysql://localhost:3306/coursedb2?serverTimezone=UTC
spring.shardingsphere.datasource.m1.username=root
spring.shardingsphere.datasource.m1.password=123666#以下是新增部分
spring.shardingsphere.sharding.tables.user.key-generator.column=userid
spring.shardingsphere.sharding.tables.user.key-generator.type=SNOWFLAKE
spring.shardingsphere.sharding.tables.user.key-generator.props.worker.id=1spring.shardingsphere.sharding.tables.user.actual-data-nodes=m$->{0..1}.user_$->{1..2}
spring.shardingsphere.sharding.tables.user_course_info.actual-data-nodes=m$->{0..1}.user_course_info_$->{1..2}spring.shardingsphere.sharding.tables.user.table-strategy.inline.sharding-column=userid
spring.shardingsphere.sharding.tables.user.table-strategy.inline.algorithm-expression=user_$->{Math.abs(userid.hashCode()%4).intdiv(2) +1}spring.shardingsphere.sharding.tables.user_course_info.table-strategy.inline.sharding-column=userid
spring.shardingsphere.sharding.tables.user_course_info.table-strategy.inline.algorithm-expression=user_course_info_$->{Math.abs(userid.hashCode()%4).intdiv(2) +1}spring.shardingsphere.sharding.binding-tables[0]=user,user_course_info

绑定表有什么作用呢?

举例生产场景:订单表和订单详情表,这两张表分片键的值是相同的,也就是说在相同分片规则的情况下,关联的数据一定会被分配到同一个分片中,所以直接到指定分片查询就可以了。绑定表在生产上非常常用,当分片数量很多时,比如64分片,试想不使用绑定表的情况下要如何查询(64*64的笛卡尔积,业务上肯定不能接受)

主从模式

早期版本叫主从模式,后续版本叫读写分离,主从做的事情其实就是读写分离。

主从参考配置:

spring.shardingsphere.props.sql.show=truespring.shardingsphere.datasource.names=m0,m1spring.shardingsphere.datasource.m0.type=com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.m0.driver-class-name=com.mysql.cj.jdbc.Driver
spring.shardingsphere.datasource.m0.url=jdbc:mysql://localhost:3306/coursedb?serverTimezone=UTC
spring.shardingsphere.datasource.m0.username=root
spring.shardingsphere.datasource.m0.password=123666spring.shardingsphere.datasource.m1.type=com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.m1.driver-class-name=com.mysql.cj.jdbc.Driver
spring.shardingsphere.datasource.m1.url=jdbc:mysql://localhost:3306/coursedb2?serverTimezone=UTC
spring.shardingsphere.datasource.m1.username=root
spring.shardingsphere.datasource.m1.password=123666#以下是添加的部分,预期效果对dict表操作,更新到m0库,查询从m1
spring.shardingsphere.sharding.master-slave-rules.gao.master-data-source-name=m0
spring.shardingsphere.sharding.master-slave-rules.gao.slave-data-source-names[0]=m1spring.shardingsphere.sharding.tables.dict.actual-data-nodes=gao.dict
spring.shardingsphere.sharding.tables.dict.key-generator.column=dictid
spring.shardingsphere.sharding.tables.dict.key-generator.type=snowflake
spring.shardingsphere.sharding.tables.dict.key-generator.props.worker.id=1

数据加密

对指定的字段类进行加密,加密后的密文字段存在数据表的指定列中。在应用代码使用时仍然操作明文列,但是观察日志可以看出转发到真实表的sql会处理成加密列去做操作,这样就达到了我们想要的效果。

好处是,不需要应用代码中额外的加密操作,内置支持多种加密方式AES、MD5、SM3、RC4等

参跑配置:

spring.shardingsphere.props.sql.show=true
spring.main.allow-bean-definition-overriding=true
spring.shardingsphere.datasource.names=m0,m1spring.shardingsphere.datasource.m0.type=com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.m0.driver-class-name=com.mysql.cj.jdbc.Driver
spring.shardingsphere.datasource.m0.url=jdbc:mysql://localhost:3306/coursedb?serverTimezone=UTC
spring.shardingsphere.datasource.m0.username=root
spring.shardingsphere.datasource.m0.password=123666spring.shardingsphere.datasource.m1.type=com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.m1.driver-class-name=com.mysql.cj.jdbc.Driver
spring.shardingsphere.datasource.m1.url=jdbc:mysql://localhost:3306/coursedb2?serverTimezone=UTC
spring.shardingsphere.datasource.m1.username=root
spring.shardingsphere.datasource.m1.password=123666spring.shardingsphere.sharding.tables.user.actual-data-nodes=m0.user_$->{1..2}
spring.shardingsphere.sharding.tables.user.key-generator.column=userid
spring.shardingsphere.sharding.tables.user.key-generator.type=SNOWFLAKEspring.shardingsphere.sharding.encrypt-rule.encryptors.encryptor_aes.type=aes
spring.shardingsphere.sharding.encrypt-rule.encryptors.encryptor_aes.props.aes.key.value=123456
spring.shardingsphere.sharding.encrypt-rule.tables.user.columns.password.plainColumn=password
spring.shardingsphere.sharding.encrypt-rule.tables.user.columns.password.cipherColumn=password_cipher
#spring.shardingsphere.sharding.encrypt-rule.tables.user.columns.password.assistedQueryColumn=user_assisted
spring.shardingsphere.sharding.encrypt-rule.tables.user.columns.password.encryptor=encryptor_aes

影子库

主要是用在压测的场景,比如说你的业务开发完了,需要测试性能,这个时候最好的情况是压测环境和生产的环境是一样的,影子库就是和生产环境的库是一样的,但是数据不同。在操作生产环境的库时,ShardingSphere内部会转发到影子库去完成测试。但是要注意,既然是压测,对生产环境的性能肯定是有影响的

这里参考配置就不列举了,因为笔者也没测试过,感兴趣的参考官方文档测试效果

总结

学习时建议多关注各种策略的思想(结合虚拟库、真实表等核心概念理解记忆),而且学习ShardingSphere强烈推荐结合官方文档自己多多尝试。使用其实不难的,关键是要找对方法,网上文章千千万,版本也是千奇百怪,初学者看的配置越多可能越不理解,ShardingSphere每个大版本的配置项都有很多改进,所以笔者建议理解每种策略存在的意义,解决问题的思想才是更有价值的。

基本技能:至少要了解每种策略是干什么用的?适合哪些场景?如何参考官方文档配置落地?

高级功能:5.x版本提供的可插拔扩展点使用,比如分片算法策略扩展、路由策略扩展、转发到真实表前的扩展(加密脱敏等)、jdbc数据库扩展、甚至sql的解析规则扩展等(建议学习SPI的扩展方式,源码中大量使用)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/233504.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

小白入门基础 - tomcat

一:前言 Tomcat 服务器是一个免费的开放源代码的 Web 应用服务器,属于轻量级应用服务器,在中小型系统和并发访问用户不是很多的场合下被普遍使用,是开发和调试JSP 程序的首选。对于一个初学者来说,可以这样认为&#x…

分布式【zookeeper面试题23连问】

1. ZooKeeper是什么? ZooKeeper是一个分布式的,开放源码的分布式应用程序协调服务,是Google的Chubby一个开源的实现,它是集群的管理者,监视着集群中各个节点的状态根据节点提交的反馈进行下一步合理操作。最终&#x…

Spring Boot 完善订单【五】集成接入支付宝沙箱支付

1.1.什么是沙箱支付 支付宝沙箱支付(Alipay Sandbox Payment)是支付宝提供的一个模拟支付环境,用于开发和测试支付宝支付功能的开发者工具。在真实的支付宝环境中进行支付开发和测试可能涉及真实资金和真实用户账户,而沙箱环境则提…

【C++】STL 算法 ⑥ ( 二元谓词 | std::sort 算法简介 | 为 std::sort 算法设置 二元谓词 排序规则 )

文章目录 一、二元谓词1、二元谓词简介2、 std::sort 算法简介3、 代码示例 - 为 std::sort 算法设置 二元谓词 排序规则 一、二元谓词 1、二元谓词简介 " 谓词 ( Predicate ) " 是一个 返回 布尔 bool 类型值 的 函数对象 / 仿函数 或 Lambda 表达式 / 普通函数 , …

安全数据交换系统:有效提升网间文件交换能力

各级政府部门和金融、能源、电力这些行业,以及一些大中型企业组织,为了保护内部的重要数据不外泄,普遍都采用了多网络并行的方式,也是做了网络隔离划分,不同的网络拥有不同的密级以及人员权限。然后再通过安全数据交换…

java中使用redis

1、redis数据类型 1.1、5种数据类型 redis存储的是key-value结构的数据,其中key是字符串类型,value有5种常用的数据类型:字符串 string、哈希 hash、列表 list、集合 set、有序集合 sorted set / zset。 字符串(string):普通字符…

Day1Qt

1、实现登录窗口界面 头文件 #ifndef MAINWINDOW_H #define MAINWINDOW_H#include <QMainWindow> #include <QIcon>//图标 #include <QLabel>//标签类 #include <QMovie>//动态类 #include <QLineEdit>//行编辑类 #include <QPushButton>…

promethues grafana 安装和使用

文章目录 1、promethues安装2、node-exporter安装3、grafana安装4、配置promethues监控node节点5、grafana操作外传 Docker 镜像下载地址&#xff1a; https://hub.docker.com 比较好的hub.docker.com///-- https://hub.docker.com/u/bitnami grafana监控面板&#xff1a;https…

电子学会C/C++编程等级考试2023年12月(三级)真题解析

C/C++编程(1~8级)全部真题・点这里 第1题:因子问题 任给两个正整数N、M,求一个最小的正整数a,使得a和(M-a)都是N的因子。 时间限制:10000 内存限制:65536 输入 包括两个整数N、M。N不超过1,000,000。 输出 输出一个整数a,表示结果。如果某个案例中满足条件的正整数不存…

使用Python+selenium3.0实现第一个自动化测试脚本

这篇文章主要介绍了使用Pythonselenium实现第一个自动化测试脚本&#xff0c;文中通过示例代码介绍的非常详细&#xff0c;对大家的学习或者工作具有一定的参考学习价值&#xff0c;需要的朋友们下面随着小编来一起学习学习吧 最近在学web自动化&#xff0c;记录一下学习过程。…

【算法与数据结构】70、LeetCode爬楼梯

文章目录 一、题目二、解法三、完整代码 所有的LeetCode题解索引&#xff0c;可以看这篇文章——【算法和数据结构】LeetCode题解。 一、题目 二、解法 思路分析&#xff1a;   程序如下&#xff1a; 复杂度分析&#xff1a; 时间复杂度&#xff1a; O ( ) O() O()。空间复…

【React系列】高阶组件

本文来自#React系列教程&#xff1a;https://mp.weixin.qq.com/mp/appmsgalbum?__bizMzg5MDAzNzkwNA&actiongetalbum&album_id1566025152667107329) 一. 高阶组件 1.1. 认识高阶组件 什么是高阶组件呢&#xff1f;相信很多同学都听说过&#xff0c;也用过 高阶函数&…

mysql高可用方案之MHA

mysql集群高可用方案&#xff1a; 单主&#xff1a;keepalived、MHA、MMM 多主&#xff1a;MySQL cluster 、PXC MHA的工作原理 MHA node 运行在每台MySQL服务器上&#xff0c;MHA Manager会定时探测集群中的master节点&#xff0c;当master出现故障时&#xff0c;它可以自…

Java方法用法及解析

在 Java 中&#xff0c;方法&#xff08;Method&#xff09;是用于执行特定任务的代码块。它是一个函数&#xff0c;用于封装一段可重复执行的代码&#xff0c;并可以被其他代码调用。方法定义了一系列操作的步骤&#xff0c;并提供了一种结构化和可复用的方式来组织和执行这些…

[VUE]4-状态管理vuex

目录 状态管理 vuex 1、vuex 介绍 2、安装 3、使用方式 4、总结 &#x1f343;作者介绍&#xff1a;双非本科大三网络工程专业在读&#xff0c;阿里云专家博主&#xff0c;专注于Java领域学习&#xff0c;擅长web应用开发、数据结构和算法&#xff0c;初步涉猎Python人工智…

【源码预备】Calcite基础知识与概念:关系代数概念、查询优化、sql关键字执行顺序以及calcite基础概念

文章目录 一. 关系代数的基本知识二. 查询优化三. SQL语句的解析顺序1. FROM2. WHERE3. GROUP BY4. HAVING5. SELECT 四. Apache Calcite中的基本概念1. Adapter2. Calcite中的关系表达式2.1. 关系表达式例子2.2. 源码底层结构 3. Calcite的优化规则4. Calcite的Trait--算子物理…

02 Deep learning algorithm

Neural Networks target&#xff1a; inference&#xff08;prediction&#xff09;training my own modelpractical advice for building machine learning systemdecision Tress application: speech&#xff08;语音识别&#xff09; ----> images(计算机视觉)—> t…

数据结构-测试4

一、判断题 1.队列结构的顺序存储会产生假溢出现象。 &#xff08;T&#xff09; 2.度为二的树就是二叉树。(F) 二叉树的度可以小于等于2 3. 栈是插入和删除只能在一端进行的线性表&#xff1b;队列是插入在一端进行&#xff0c;删除在另一端进行的线性表。&#xff08;T&…

【CMake】1. VSCode 开发环境安装与运行

CMake 示例工程代码 https://github.com/LABELNET/cmake-simple 插件 使用 VSCode 开发C项目&#xff0c;安装 CMake 插件 CMakeCMake ToolsCMake Language Support &#xff08;建议&#xff0c;语法提示) 1. 配置 CMake Language Support , Windows 配置 donet 环境 这…

异地环控设备如何远程维护?贝锐蒲公英解决远程互联难题

青岛某企业致力于孵化设备、养禽设备和养猪设备的研发、生产和服务&#xff0c;历经三十多年发展&#xff0c;目前已成长为行业主要的养殖装备及工程服务提供商&#xff0c;产品覆盖养殖产业链中绝大多数环节&#xff0c;涉及自动化设备、环控设备、整体解决方案等。 在实际应用…