ShardingSphere分库分表2-ShardingJDBC实战

更新时间:2023-05-12 08:57:28 阅读: 评论:0

ShardingSphere分库分表2-ShardingJDBC实战
⽂章⽬录
⼀、ShardingSphere
ShardingSphere是⼀款起源于当当⽹内部的应⽤框架。2015年在当当⽹内部诞⽣,最初就叫ShardingJDBC。2016年的时候,由其中⼀个主要的开发⼈员张亮,带⼊到京东数科,组件团队继续开发。在国内历经了当当⽹、电信翼⽀付、京东数科等多家⼤型互联⽹企业的考验,在2017年开始开源。并逐渐由原本只关注于关系型数据库增强⼯具的ShardingJDBC升级成为⼀整套以数据分⽚为基础的数据⽣态圈,更名为ShardingSphere。到2020年4⽉,已经成为了Apache软件基⾦会的顶级项⽬。
ShardingSphere包含三个重要的产品,ShardingJDBC、ShardingProxy和ShardingSidecar。其中sidecar是针对rvice mesh定位的⼀个分库分表插件,⽬前在规划中。⽽我们今天学习的重点是ShardingSphere的JDBC和Proxy这两个组件。
其中,ShardingJDBC是⽤来做客户端分库分表的产品,⽽ShardingProxy是⽤来做服务端分库分表的产品。这两者定位有什么区别呢?我们看下官⽅资料中给出的两个重要的图:
ShardingJDBC:
shardingJDBC定位为轻量级 Java 框架,在 Java 的 JDBC 层提供的额外服务。它使⽤客户端直连数据库,以 jar 包形式提供服务,⽆需额外部署和依赖,可理解为增强版的 JDBC 驱动,完全兼容 JDBC 和各种 ORM 框架。
ShardingProxy
ShardingProxy定位为透明化的数据库代理端,提供封装了数据库⼆进制协议的服务端版本,⽤于完成对异构语⾔的⽀持。⽬前提供MySQL 和 PostgreSQL 版本,它可以使⽤任何兼容 MySQL/PostgreSQL 协议的访问客⼾端。
那这两种⽅式有什么区别呢?
Sharding-JDBC Sharding-Proxy
数据库任意MySQL/PostgreSQL
连接消耗数⾼低
异构语⾔仅java任意
性能损耗低损耗略⾼
⽆中⼼化是否
静态⼊⼝⽆有
很显然,ShardingJDBC只是客户端的⼀个⼯具包,可以理解为⼀个特殊的JDBC驱动包,所有分库分表逻辑均由业务⽅⾃⼰控制,所以他的功能相对灵活,⽀持的数据库也⾮常多,但是对业务侵⼊⼤,需要业务⽅⾃⼰定制所有的分库分表逻辑。⽽ShardingProxy是⼀个独⽴部署的服务,对业务⽅⽆侵⼊,业务⽅可以像⽤⼀个普通的MySQL服务⼀样进⾏数据交互,基本上感觉不到后端分库分表逻辑的存在,但是这也意味着功能会⽐较固定,能够⽀持的数据库也⽐较少。这两者各有优劣。
⼆、ShardingJDBC实战
shardingjdbc的核⼼功能是数据分⽚和读写分离,通过ShardingJDBC,应⽤可以透明的使⽤JDBC访问已经分库分表、读写分离的多个数据源,⽽不⽤关⼼数据源的数量以及数据如何分布。
1、核⼼概念:
逻辑表:⽔平拆分的数据库的相同逻辑和数据结构表的总称
真实表:在分⽚的数据库中真实存在的物理表。
数据节点:数据分⽚的最⼩单元。由数据源名称和数据表组成
绑定表:分⽚规则⼀致的主表和⼦表。
⼴播表:也叫公共表,指素有的分⽚数据源中都存在的表,表结构和表中的数据在每个数据库中都完全⼀致。例如字典表。
分⽚键:⽤于分⽚的数据库字段,是将数据库(表)进⾏⽔平拆分的关键字段。SQL中若没有分⽚字段,将会执⾏全路由,性能会很差。
分⽚算法:通过分⽚算法将数据进⾏分⽚,⽀持通过=、BETWEEN和IN分⽚。分⽚算法需要由应⽤开发者⾃⾏实现,可实现的灵活度⾮常⾼。
分⽚策略:真正⽤于进⾏分⽚操作的是分⽚键+分⽚算法,也就是分⽚策略。在ShardingJDBC中⼀般
采⽤基于Groovy表达式的inline 分⽚策略,通过⼀个包含分⽚键的算法表达式来制定分⽚策略,如t_ur_$->{u_id%8}标识根据u_id模8,分成8张表,表名称为t_ur_0到t_ur_7。
2、测试项⽬介绍
测试项⽬参见配套的ShardingDemo项。⾸先我们对测试项⽬的结构做下简单的梳理:
注:1、引⼊MyBatisPlus依赖,简化JDBC操作,这样我们就不需要在代码中写SQL语句了。
2、entity中的实体对象就对应数据库中的表结构。⽽mapper中的接⼝则对应JDBC操作。
3、所有操作均使⽤JUnit的测试案例执⾏。 后续所有测试操作都会配合application.properties中的配置以及JUnit测试案例进⾏。
4、关于ShardingSphere版本,由于⽬前最新的5.0版本还在孵化当中,所以我们使⽤已发布的4.1.1版本来进⾏学习。
3、快速实战
我们先运⾏⼀个简单的实例,来看下ShardingJDBC是如何⼯作的。
在application.properties配置⽂件中写⼊application01.properties⽂件的内容:
#垂直分表策略
# 配置真实数据源
spring.shardingsphere.datasource.names=m1
# 配置第 1 个数据源
spring.shardingsphere.pe=com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.m1.sql.cj.jdbc.Driver
spring.shardingsphere.datasource.m1.url=jdbc:mysql://localhost:3306/courdb?rverTimezone=GMT%2B8
spring.shardingsphere.datasource.m1.urname=root
spring.shardingsphere.datasource.m1.password=root
# 指定表的分布情况配置表在哪个数据库⾥,表名是什么。⽔平分表,分两个表:m1.cour_ur_2
spring.shardingsphere.ur.ur_$->{1..2}
# 指定表的主键⽣成策略
spring.shardingsphere.lumn=cid
spring.shardingsphere.pe=SNOWFLAKE
#雪花算法的⼀个可选参数
spring.shardingsphere.ur.key-generator.props.worker.id=1
#使⽤⾃定义的主键⽣成策略
#spring.shardingsphere.pe=MYKEY
#spring.shardingsphere.ur.key-offt=88
#指定分⽚策略约定cid值为偶数添加到cour_1表。如果是奇数添加到cour_2表。
# 选定计算的字段
spring.shardingsphere.ur.table-strategy.inline.sharding-column= cid
# 根据计算的字段算出对应的表名。
spring.shardingsphere.ur.table-strategy.inline.algorithm-expression=cour_$->{cid%2+1}
# 打开sql⽇志输出。
spring.shardingsphere.props.sql.show=true
spring.main.allow-bean-definition-overriding=true
1、⾸先定义⼀个数据源m1,并对m1进⾏实际的JDBC参数配置
2、spring.shardingsphere.ur开头的⼀系列属性即定义了⼀个名为cour的逻辑表。
actual-data-nodes属性即定义cour逻辑表的实际数据分布情况,他分布在m1.cour_1和m1.cour
_2两个表。
key-generator属性配置了他的主键列以及主键⽣成策略。ShardingJDBC默认提供了UUID和SNOWFLAKE两种分布式主键⽣成策略。
table-strategy属性即配置他的分库分表策略。分⽚键为cid属性。分⽚算法为cour_$->{cid%2+1},表⽰按照cid模2+1的结果,然后加上前⾯的cour__ 部分作为前缀就是他的实际表结果。注意,这个表达式计算出来的结果需要能够与实际数据分布中的⼀种情况对应上,否则就会报错。
sql.show属性表⽰要在⽇志中打印实际SQL
3、courdb的表结构见⽰例中sql⽂件夹中的sql语句。
然后我们执⾏测试案例中的addcour案例。
执⾏后,我们可以在控制台看到很多条这样的⽇志:
.......
2020-12-15 18:35:16.426  INFO 22412 --- [          main] ShardingSphere-SQL                      : Logic SQL: INSERT INTO cour  ( cname,
ur_id,
cstatus )  VALUES  ( ?,
,
)
2020-12-15 18:35:16.427  INFO 22412 --- [          main] ShardingSphere-SQL                      : SQLStatement: InrtStatementContext(super=CommonSQL StatementContext(sqlStatement=org.apache.shardingsphere.sql.parr.sql.statement.dml.InrtStatement@1cbc5693, tablesContext=org.apache.shardin gsphere.sql.table.TablesContext@124d26ba), tablesContext=org.apache.shardingsphere.sql.table.TablesC ontext@124d26ba, columnNames=[cname, ur_id, cstatus], inrtValueContexts=[InrtValueContext(parametersCount=3, valueExpressions=[Paramete rMarkerExpressionSegment(
startIndex=59, stopIndex=59, parameterMarkerIndex=0), ParameterMarkerExpressionSegment(startIndex=62, stopIndex=62, parameterMarkerIndex=1), ParameterMarkerExpressionSegment(startIndex=65, stopIndex=65, parameterMarkerIndex=2), DerivedParameterMarkerExpr essionSegment(super=ParameterMarkerExpressionSegment(startIndex=0, stopIndex=0, parameterMarkerIndex=3))], parameters=[java, 1001, 1])], gener atedKeyContext=Optional[GeneratedKeyContext(columnName=cid, generated=true, generatedValues=[545674405561237505])])
2020-12-15 18:35:16.427  INFO 22412 --- [          main] ShardingSphere-SQL                      : Actual SQL: m1 ::: INSERT INTO cour_2  ( cname,
ur_id,
cstatus , cid)  VALUES  (?, ?, ?, ?) ::: [java, 1001, 1, 545674405561237505]
.....
从这个⽇志中我们可以看到,程序中执⾏的Logic SQL经过ShardingJDBC处理后,被转换成了Actual
SQL往数据库⾥执⾏。执⾏的结果可以在MySQL中看到,cour_1和cour_2两个表中各插⼊了五条消息。这就是ShardingJDBC帮我们进⾏的数据库的分库分表操作。
然后,其他的⼏个配置⽂件依次对应了其他⼏种分库分表策略,我们可以⼀⼀演⽰⼀下。
application02.properties: 分库分表⽰例配置。内置分⽚算法⽰例, inline、standard、complex、hint。⼴播表配置⽰例。
application03.properties: 绑定表⽰例配置
application04.properties: 读写分离⽰例配置
要注意理解在读写分离策略中,ShardingJDBC只能帮我们把读写操作分发到不同的数据库上,⽽数据库之间的数据同步,还是需要由MySQL主从集群来完成。
4、ShardingJDBC的分⽚算法
ShardingJDBC的整个实战完成后,可以看到,整个分库分表的核⼼就是在于配置的分⽚算法。我们
的这些实战都是使⽤的inline分⽚算法,即提供⼀个分⽚键和⼀个分⽚表达式来制定分⽚算法。这种⽅式配置简单,功能灵活,是分库分表最佳的配置⽅式,并且对于绝⼤多数的分库分⽚场景来说,都已经⾮常好⽤了。但是,如果针对⼀些更为复杂的分⽚策略,例如多分⽚键、按范围分⽚等场景,inline分⽚算法就有点⼒不从⼼了。所以,我们还需要学习下ShardingSphere提供的其他⼏种分⽚策略。
ShardingSphere⽬前提供了⼀共五种分⽚策略:
NoneShardingStrategy
不分⽚。这种严格来说不算是⼀种分⽚策略了。只是ShardingSphere也提供了这么⼀个配置。
InlineShardingStrategy
最常⽤的分⽚⽅式
配置参数: inline.shardingColumn 分⽚键;inline.algorithmExpression 分⽚表达式
实现⽅式: 按照分⽚表达式来进⾏分⽚。
StandardShardingStrategy
只⽀持单分⽚键的标准分⽚策略。
配置参数:standard.sharding-column 分⽚键;standard.preci-algorithm-class-name 精确分⽚算法类名;
standard.range-algorithm-class-name 范围分⽚算法类名
实现⽅式:
shardingColumn指定分⽚算法。
preciAlgorithmClassName 指向⼀个实现了
io.shardingsphere.api.algorithm.sharding.standard.PreciShardingAlgorithm接⼝的java类名,提供按照 = 或者 IN 逻辑的精确分⽚ ⽰例:shardingDemo.algorithm.MyPreciShardingAlgorithm
rangeAlgorithmClassName 指向⼀个实现了
io.shardingsphere.api.algorithm.sharding.standard.RangeShardingAlgorithm接⼝的java类名,提供按
照Between 条件进⾏的范围分⽚。⽰例:shardingDemo.algorithm.MyRangeShardingAlgorithm
说明:
其中精确分⽚算法是必须提供的,⽽范围分⽚算法则是可选的。
ComplexShardingStrategy
⽀持多分⽚键的复杂分⽚策略。
配置参数:complex.sharding-columns 分⽚键(多个); complex.algorithm-class-name 分⽚算法实现类。
实现⽅式:
shardingColumn指定多个分⽚列。
algorithmClassName指向⼀个实现了
org.apache.shardingsphere.plex.ComplexKeysShardingAlgorithm接⼝的java类名。
提供按照多个分⽚列进⾏综合分⽚的算法。⽰例:shardingDemo.algorithm.MyComplexKeysShardingAlgorithm
HintShardingStrategy
不需要分⽚键的强制分⽚策略。这个分⽚策略,简单来理解就是说,他的分⽚键不再跟SQL语句相关联,⽽是⽤程序另⾏指定。对于⼀些复杂的情况,例如lect count(*) from (lect urid from t_ur where urid in (1,3,5,7,9)) 这样的SQL语句,就没法通过SQL语句来指定⼀个分⽚键。这个时候就可以通过程序,给他另⾏执⾏⼀个分⽚键,例如在按urid奇偶分⽚的策略下,可以指定1作为分⽚键,然后⾃⾏指定他的分⽚策略。
配置参数:hint.algorithm-class-name 分⽚算法实现类。
实现⽅式:
algorithmClassName指向⼀个实现了org.apache.shardingsphere.api.sharding.hint.HintShardingAlgorithm接⼝的java类名。 ⽰例:shardingDemo.algorithm.MyHintShardingAlgorithm
在这个算法类中,同样是需要分⽚键的。⽽分⽚键的指定是通过HintManager.addDatabaSharding
Value⽅法(分库)和HintManager.addTableShardingValue(分表)来指定。
使⽤时要注意,这个分⽚键是线程隔离的,只在当前线程有效,所以通常建议使⽤之后⽴即关闭,或者⽤try资源⽅式打开。
⽽Hint分⽚策略并没有完全按照SQL解析树来构建分⽚策略,是绕开了SQL解析的,所有对某些⽐较复杂的语句,Hint分⽚策略性能有可能会⽐较好(情况太多了,⽆法⼀⼀分析)。
但是要注意,Hint强制路由在使⽤时有⾮常多的限制:
-- 不⽀持UNION
SELECT*FROM t_order1 UNION SELECT*FROM t_order2
INSERT INTO tbl_name (col1, col2, …)SELECT col1, col2, … FROM tbl_name WHERE col3 = ?
-- 不⽀持多层⼦查询
SELECT COUNT(*)FROM(SELECT*FROM t_order o WHERE o.id IN(SELECT id FROM t_order WHERE status= ?))
-
- 不⽀持函数计算。ShardingSphere只能通过SQL字⾯提取⽤于分⽚的值
SELECT*FROM t_order WHERE to_date(create_time,'yyyy-mm-dd')='2019-01-01';

本文发布于:2023-05-12 08:57:28,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/fan/82/597302.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:策略   分库   分表   数据库
相关文章
留言与评论(共有 0 条评论)
   
验证码:
推荐文章
排行榜
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图