Springboot整合ShardingSphere实现分库分表,读写分离

Springboot整合ShardingSphere实现分库分表,读写分离
彼岸的風ShardingSphere简介
Apache ShardingSphere 是一款分布式的数据库生态系统, 可以将任意数据库转换为分布式数据库,并通过数据分片、弹性伸缩、加密等能力对原有数据库进行增强。它由Sharding-JDBC、Sharding-Proxy和Sharding-Sidecar(计划中)这3款相互独立的产品组成,我们只关注 Sharding-JDBC 即可。Sharding-JDBC 定位为轻量级Java框架,在Java的JDBC层提供的额外服务。 它使用客户端直连数据库,以jar包形式提供服务,无需额外部署和依赖,可理解为增强版的JDBC驱动,完全兼容JDBC和各种ORM框架的使用。Sharding-JDBC 主要功能:数据分片 和 读写分离 通过Sharding-JDBC ,应用可以透明的使用jdbc访问已经分库分表、读写分离的多个数据源,而不用关心数据源的数量以及数据如何分布。
SpringBoot整合ShardingSphere
本次记录项目版本为SpringBoot(2.4.0),ShardingSphere(4.0.0-RC1)
ShardingSphere读写分离
- 拟定我们要为订单表实现读写分离,插入,修改在主库 ds0 中进行,查询在从库 ds1 中操作。
- 先创建订单表,这里是用本地运行2个MYSQL服务分别在库中创建,具体实现请参考本地同时运行多个MYSQL服务一文。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18DROP TABLE IF EXISTS `fu_order`;
CREATE TABLE `fu_order` (
`id` bigint NOT NULL AUTO_INCREMENT COMMENT '订单id',
`user_id` int DEFAULT NULL COMMENT '用户id',
`product_id` int DEFAULT NULL COMMENT '商品id',
`order_no` bigint DEFAULT NULL COMMENT '订单号',
`quantity` int DEFAULT NULL COMMENT '商品数量',
`total_price` decimal(20,2) DEFAULT NULL COMMENT '商品总价,单位(元)保留2位小数点',
`status` int DEFAULT NULL COMMENT '订单状态(0:已取消,1:待支付,2:已付款)',
`end_time` datetime DEFAULT NULL COMMENT '交易完成时间',
`closet_time` datetime DEFAULT NULL COMMENT '交易关闭时间',
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
`update_time` datetime DEFAULT NULL COMMENT '更新时间',
`is_deleted` tinyint(1) DEFAULT '0' COMMENT '逻辑删除',
PRIMARY KEY (`id`),
UNIQUE KEY `order_no_index` (`order_no`) USING BTREE,
UNIQUE KEY `order_no_user_id_index` (`user_id`,`order_no`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT = 1 CHARSET=utf8mb4 COMMENT='订单表'; - 在项目pom.xml中引入相关依赖
1
2
3
4
5
6
7
8
9
10
11
12<!-- 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-jdbc-spring-namespace</artifactId>
<version>4.0.0-RC1</version>
</dependency> - 配置文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41spring:
jackson:
time-zone: GMT+8
# shardingsphere 读写分离配置
main:
allow-bean-definition-overriding: true # 启动项目报bean冲突配置(shardingsphere/mybatisplus)
shardingsphere:
enabled: true
datasource:
ds0:
type: com.zaxxer.hikari.HikariDataSource
jdbc-url: ENC(1Ec2OVfgDl1nKRf4f2wXI1f1uhLa2FCc3Aw3mxVnChU64rlqO/PemyFSfHK/G0n5DQySOKllf3A/LJKKaUNfIS+ZoYKiODV40FmaVac+62XDlzdhU3qigmwTdfWNyihK7Peng+8wmiMiuziXe5huVpNoUbKD+9pj)
password: ENC(j/o7k6nZe+yAMoWVWRnjFg==)
username: ENC(ytrxf1igA4bazqZ6TOOc1A==)
ds1:
type: com.zaxxer.hikari.HikariDataSource
jdbc-url: ENC(rHDezuPA7GdjUHe+RP7cdZlOx/O4TjoTOfsncXmePbm8b27Viocz2YZJvORLoAl8KiV5Qs/f2OjzaJ+cBFHwG5p29u0Yuj37tGNVqiP64qWTU9U2AL8GgQY38VeAJl3O72vxPxOpwnGnsyFWNzLFqX0boEhQIaEX)
password: ENC(j/o7k6nZe+yAMoWVWRnjFg==)
username: ENC(ytrxf1igA4bazqZ6TOOc1A==)
# 配置数据源
names: ds0,ds1
masterslave:
# 配置slave节点的负载均衡均衡策略,采用轮询机制
load-balance-algorithm-type: round_robin
# 配置主库master,负责数据的写入
master-data-source-name: ds0
# 配置主从名称
name: ms
# 配置从库slave节点
slave-data-source-names: ds1
props:
sql:
show: true
sharding:
# 配置默认数据源ds1 默认数据源,主要用于写
default-data-source-name: ds0
mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
mapper-locations: com/fu99999/note/mapper/xml/*.xml
type-aliases-package: com.ppdai.shardingjdbc.entity # shardingjdbc整合mybatis的配置 - 测试
- 启动项目创建一个新订单,控制台输出如图,Insert语句是在ds0主库中的表执行。
- 我们在查询刚插入的这条订单信息,可以看出select语句是在ds1从库执行,所以没有查到数据。
- 需要配置数据库主从同步才能在从库中查到数据,请参考MQSQL主从数据同步配置一文。
ShardingSphere分库分表
- 分别在3306库和3307库创建3张订单表,根据id字段取模确定最终数据的位置,数据库环境配置如下:
1
2
3
4
5
6
7
8
9
10localhost:3306
wind-of-grace
fu_order_0
fu_order_1
fu_order_2
localhost:3307
wind-of-grace
fu_order_0
fu_order_1
fu_order_2 - 三张表的逻辑表为fu_order_0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18DROP TABLE IF EXISTS `fu_order_0`;
CREATE TABLE `fu_order_0` (
`id` bigint NOT NULL COMMENT '订单id',
`user_id` int DEFAULT NULL COMMENT '用户id',
`product_id` int DEFAULT NULL COMMENT '商品id',
`order_no` bigint DEFAULT NULL COMMENT '订单号',
`quantity` int DEFAULT NULL COMMENT '商品数量',
`total_price` decimal(20,2) DEFAULT NULL COMMENT '商品总价,单位(元)保留2位小数点',
`status` int DEFAULT NULL COMMENT '订单状态(0:已取消,1:待支付,2:已付款)',
`end_time` datetime DEFAULT NULL COMMENT '交易完成时间',
`closet_time` datetime DEFAULT NULL COMMENT '交易关闭时间',
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
`update_time` datetime DEFAULT NULL COMMENT '更新时间',
`is_deleted` tinyint(1) DEFAULT '0' COMMENT '逻辑删除',
PRIMARY KEY (`id`),
UNIQUE KEY `order_no_index` (`order_no`) USING BTREE,
UNIQUE KEY `order_no_user_id_index` (`user_id`,`order_no`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='订单表_0'; - 配置文件
定义分库分表规则:根据主键分片,偶数主键的记录放入ds0库(或表),奇数主键的记录放入ds1库(或表)1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49spring:
jackson:
time-zone: GMT+8
# shardingsphere 分库分表配置
# 启动项目报bean冲突配置(shardingsphere/mybatisplus)
main:
allow-bean-definition-overriding: true
shardingsphere:
# 是否启用
enabled: true
datasource:
ds0:
type: com.zaxxer.hikari.HikariDataSource
driverClassName: com.mysql.jdbc.Driver
jdbc-url: ENC(1Ec2OVfgDl1nKRf4f2wXI1f1uhLa2FCc3Aw3mxVnChU64rlqO/PemyFSfHK/G0n5DQySOKllf3A/LJKKaUNfIS+ZoYKiODV40FmaVac+62XDlzdhU3qigmwTdfWNyihK7Peng+8wmiMiuziXe5huVpNoUbKD+9pj)
password: ENC(j/o7k6nZe+yAMoWVWRnjFg==)
username: ENC(ytrxf1igA4bazqZ6TOOc1A==)
ds1:
type: com.zaxxer.hikari.HikariDataSource
driverClassName: com.mysql.jdbc.Driver
jdbc-url: ENC(rHDezuPA7GdjUHe+RP7cdZlOx/O4TjoTOfsncXmePbm8b27Viocz2YZJvORLoAl8KiV5Qs/f2OjzaJ+cBFHwG5p29u0Yuj37tGNVqiP64qWTU9U2AL8GgQY38VeAJl3O72vxPxOpwnGnsyFWNzLFqX0boEhQIaEX)
password: ENC(j/o7k6nZe+yAMoWVWRnjFg==)
username: ENC(ytrxf1igA4bazqZ6TOOc1A==)
# 配置ds0 和ds1两个数据源
names: ds0,ds1
# 打印SQL
props:
sql:
show: true
# 分库策略 根据id取模确定数据进哪个数据库 偶数存ds0库/表 奇数存ds1库/表
sharding:
default-database-strategy:
inline:
algorithm-expression: ds$->{id % 2}
sharding-column: id
# 具体分表策略
tables:
fu_order:
actual-data-nodes: ds$->{0..1}.fu_order_$->{0..2}
# ※千万不能将主键的生成规则设置成自增长,需要按照一定规则来生成主键,这里使用shardingsphere中的SNOWFLAKE俗称雪花算法来生成主键
key-generator:
column: id
type: SNOWFLAKE # 使用SNOWFLAKE算法生成主键
# 分表字段id
# 分表策略 根据id取模,确定数据最终落在那个表中
table-strategy:
inline:
algorithm-expression: fu_order_$->{id % 3}
sharding-column: id - 测试
- 启动项目创建几个订单,观察控制台输出
- 根据分库分表规则,订单被分别插入到ds1库中的fu_order_0表和ds0库中的fu_order_1表中
评论
匿名评论隐私政策
✅ 你无需删除空行,直接评论以获取最佳展示效果