使⽤ShardingSphere实现分库分表以及事务回滚含性能测试(附代码)
1.简介
Apache ShardingSphere 是⼀套开源的分布式数据库解决⽅案组成的⽣态圈,它由 JDBC、Proxy 和 Sidecar(规划中)这 3 款既能够独⽴部署,⼜⽀持混合部署配合使⽤的产品组成。 它们均提供标准化的数据⽔平扩展、分布式事务和分布式治理等功能,可适⽤于如 Java 同构、异构语⾔、云原⽣等各种多样化的应⽤场景。
Apache ShardingSphere 旨在充分合理地在分布式的场景下利⽤关系型数据库的计算和存储能⼒,⽽并⾮实现⼀个全新的关系型数据库。关系型数据库当今依然占有巨⼤市场份额,是企业核⼼系统的基⽯,未来也难于撼动,我们更加注重在原有基础上提供增量,⽽⾮颠覆。
Apache ShardingSphere 5.x 版本开始致⼒于可插拔架构,项⽬的功能组件能够灵活的以可插拔的⽅式进⾏扩展。 ⽬前,数据分⽚、读写分离、数据加密、影⼦库压测等功能,以及 MySQL、PostgreSQL、SQLServer、Oracle 等 SQL 与协议的⽀持,均通过插件的⽅式织⼊项⽬。 开发者能够像使⽤积⽊⼀样定制属于⾃⼰的独特系统。Apache ShardingSphere ⽬前已提供数⼗个 SPI 作为系统的扩展点,仍在不断增加中。
triumphal2.ShardingSphere的核⼼概念
分⽚
⼀般我们在提到分库分表的时候,⼤多是以⽔平切分模式(⽔平分库、分表)为基础来说的,数据分⽚将原本⼀张数据量较⼤的表t_order 拆分⽣成数个表结构完全⼀致的⼩数据量表 t_order_0、t_order_1、···、t_order_n,每张表只存储原⼤表中的⼀部分数据,当执⾏⼀条SQL时会通过 分库策略、分⽚策略 将数据分散到不同的数据库、表内。
数据节点
数据节点是分库分表中⼀个不可再分的最⼩数据单元(表),它由数据源名称和数据表组成,例如上图中 order_db_1.t_order_0、order_db_2.t_order_1 就表⽰⼀个数据节点。
逻辑表
ocam逻辑表是指⼀组具有相同逻辑和数据结构表的总称。⽐如我们将订单表t_order 拆分成 t_order_0 ··· t_order_9 等 10张表。此时我们会发现分库分表以后数据库中已不在有 t_order 这张表,取⽽代之的是 t_order_n,但我们在代码中写 SQL 依然按 t_order 来写。此时 t_order 就是这些拆分表的逻辑表。
真实表
真实表也就是上边提到的 t_order_n 数据库中真实存在的物理表。
分⽚键
⽤于分⽚的数据库字段。我们将 t_order 表分⽚以后,当执⾏⼀条SQL时,通过对字段 order_id 取模的⽅式来决定,这条数据该在哪个数据库中的哪个表中执⾏,此时 order_id 字段就是 t_order 表的分⽚健。
分布式主键
数据分⽚后,不同数据节点⽣成全局唯⼀主键是⾮常棘⼿的问题,同⼀个逻辑表(t_order)内的不同真实表(t_order_n)之间的⾃增键由于⽆法互相感知⽽产⽣重复主键。
尽管可通过设置⾃增主键 初始值 和 步⻓ 的⽅式避免ID碰撞,但这样会使维护成本加⼤,乏完整性和可扩展性。如果后去需要增加分⽚表的数量,要逐⼀修改分⽚表的步长,运维成本⾮常⾼,所以不建议这种⽅式。
建议使⽤分布式主键⽣成器等开源项⽬。
3.使⽤ShardingSphere进⾏数据库分库分表
pom
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--mybatis驱动-->
<!-- mybatis plus -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus</artifactId>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
</dependency>
<!--druid数据源-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!--shardingsphere最新版本-->
<dependency>
<groupId>org.apache.shardingsphere</groupId>
<artifactId>sharding-jdbc-spring-boot-starter</artifactId>
<version>4.0.0-RC1</version>
</dependency>
<dependency>
<groupId>org.apache.shardingsphere</groupId>
<artifactId>sharding-core-common</artifactId>
<version>4.0.0-RC1</version>
</dependency>
<dependency>
<groupId>org.apache.shardingsphere</groupId>
cookies怎么读<artifactId>sharding-jdbc-spring-namespace</artifactId>
<version>4.0.0-RC1</version>
</dependency>
<!--lombok实体⼯具-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
</dependencies>
application.yaml
rver:
port:10001
# mybatis-plus相关配置
mybatis-plus:
# xml扫描,多个⽬录⽤逗号或者分号分隔(告诉 Mapper 所对应的 XML ⽂件位置)
mapper-locations: classpath:mapper/*.xml
typeAliasPackage: com.whxd.ity
configuration:
# 是否开启⾃动驼峰命名规则映射:从数据库列名到Java属性驼峰命名的类似映射
map-underscore-to-camel-ca: true
# 如果查询结果中包含空值的列,则 MyBatis 在映射的时候,不会映射这个字段
call-tters-on-nulls: true
# log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
spring:
main:
allow-bean-definition-overriding: true
shardingsphere:
datasource:
#数据源名称,多数据源以逗号分隔
names: logs0,logs1
毫米的英文
#配置数据源具体内容,包含连接池,驱动,地址,⽤户名和密码system什么意思
logs0:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: sql.cj.jdbc.Driver
url: jdbc:mysql://x:3306/logs0?uUnicode=true&characterEncoding=utf-8&autoReconnect=true&uSSL=true&&rverTimezone=Asia/ Shanghai
urname: xxxxxx
password: xxxxxx
logs1:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: sql.cj.jdbc.Driver
url: jdbc:mysql://x:3306/logs1?uUnicode=true&characterEncoding=utf-8&autoReconnect=true&uSSL=true&&rverTimezone=Asia/ Shanghai
urname: xxxxxx
password: xxxxxx
sharding:
tables:
operator_log:
actual-data-nodes: logs$->{0..1}.operator_log_$->{0..5}
迪士尼英语动画片
table-strategy:
inline:
sharding-column: id
algorithm-expression: operator_log_$->{id % 5}
#分表策略,同分库策略
key-generator:
column: id身份证号查四级成绩
#⾃增列值⽣成器类型,缺省表⽰使⽤默认⾃增列值⽣成器。可使⽤⽤户⾃定义的列值⽣成器或选择内置类型:SNOWFLAKE/UUID
type: SNOWFLAKE
default-databa-strategy:
inline:
sharding-column: id
algorithm-expression: logs$->{id % 2}lofter是什么意思
props:
sql:
show: true
启动类
@SpringBootApplication
@MapperScan("com.whxd.sharding.web.mapper")
public class ShardingSphereApplication {
public static void main(String[] args){
SpringApplication.run(ShardingSphereApplication.class, args); }
@Bean
@ConditionalOnMissingBean
public PaginationInterceptor paginationInterceptor(){
// 开启 count 的 join 优化,只针对 left join
return new PaginationInterceptor();
}
}
controller层
/**
* <p>
* 前端控制器
* </p>
*
* @author KimWu
* @since 2021-08-09
*/
@RestController
@RequestMapping("/operatorLog")
public class OperatorLogController {
@Autowired
private IOperatorLogService operatorLogService;
@PostMapping("/inrt")
public String inrt(){
try{
for(int i =1; i<100;i++){
operatorLogService.save(build());
}
tag是什么意思啊return"成功";
}catch(Exception e){
e.printStackTrace();
return"失败";
rollover
}
}
@PostMapping("/page")
public List<OperatorLog>page(){
List<OperatorLog> list = operatorLogService.list();
return list;
}
private OperatorLog build(){
return new OperatorLog(
null,System.currentTimeMillis()+"",null,null,null,
null,null,null,null, Name(),null,null,
//随机⽣成姓名
}
}
数据库表的sql