集成shardingSphere实现读写分离
要在Spring Boot项目中集成ShardingSphere并实现读写分离,可以按照以下步骤进行配置和实现。以下是详细的配置和说明:
1. 引入依赖
在pom.xml
中添加ShardingSphere和数据库连接池的依赖。注意,ShardingSphere已经内置了数据源管理功能,因此不需要额外引入druid-spring-boot-starter
,而是直接使用druid
。
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>2.5.3</version>
<exclusions>
<exclusion>
<artifactId>snakeyaml</artifactId>
<groupId>org.yaml</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.4.3.3</version>
<exclusions>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.32</version>
</dependency>
<dependency>
<groupId>org.apache.shardingsphere</groupId>
<artifactId>shardingsphere-jdbc-core-spring-boot-starter</artifactId>
<version>5.2.1</version>
<exclusions>
<exclusion>
<artifactId>snakeyaml</artifactId>
<groupId>org.yaml</groupId>
</exclusion>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
<version>2.5.3</version>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.3.3</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.28</version>
</dependency>
<dependency>
<groupId>org.yaml</groupId>
<artifactId>snakeyaml</artifactId>
<version>1.33</version>
</dependency>
<!--引入shardingJDBC后,就不要直接使用druid-sprint-boot-starter依赖了。
因为这个依赖会在Spring容器中注入一个DataSource,这样再要使用ShardingSphere注入DataSource就会产生冲突了。-->
<!--<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.20</version>
</dependency>-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.20</version>
</dependency>
</dependencies>
2. 配置数据源和读写分离规则
在application.yml
中配置数据源和读写分离规则。以下是一个示例配置:
spring:
shardingsphere:
datasource:
names: master,slave0,slave1
master:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/masterdb?useUnicode=true&characterEncoding=utf8&useSSL=true&serverTimezone=GMT%2B8
username: root
password: 123456
slave0:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/slavedb0?useUnicode=true&characterEncoding=utf8&useSSL=true&serverTimezone=GMT%2B8
username: root
password: 123456
slave1:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/slavedb1?useUnicode=true&characterEncoding=utf8&useSSL=true&serverTimezone=GMT%2B8
username: root
password: 123456
rules:
readwrite-splitting:
data-sources:
ds:
static-strategy:
write-data-source-name: master
read-data-source-names:
- slave0
- slave1
load-balancer-name: order_lb
load-balancers:
order_lb:
type: ROUND_ROBIN
props:
sql-show: true
mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
3. 配置说明
-
数据源配置:
-
master
:主库数据源,用于写操作。 -
slave0
和slave1
:从库数据源,用于读操作。
-
-
读写分离规则:
-
ds
:逻辑数据源名称,应用程序通过该名称访问数据库。 -
write-data-source-name
:指定写操作的数据源。 -
read-data-source-names
:指定读操作的数据源列表。 -
load-balancer-name
:指定读操作的负载均衡算法。
-
-
负载均衡算法:
-
ROUND_ROBIN
:轮询算法,读请求会在slave0
和slave1
之间轮询。 -
其他可选算法:
RANDOM
(随机)、WEIGHT
(权重)等。
-
4. 测试读写分离
编写测试代码,验证读写分离是否生效。
4.1 插入数据(写操作)
@RestController
@RequestMapping("/user")
public class UserController {
@Autowired
private UserMapper userMapper;
@PostMapping("/add")
public String addUser(@RequestBody User user) {
// 插入数据
return userMapper.addUser(user);
}
}
4.2 查询数据(读操作)
@GetMapping("/detail/{id}")
public User getDetail(@PathVariable Long id) {
//查询详情
return userMapper.detail(id);
}
4.3 验证日志
-
写操作:
addUser
方法会被路由到主库(master)。 -
读操作:
getDetail
方法会被路由到从库(slave0
或slave1
)。
ShardingSphere-SQL: Logic SQL: INSERT INTO user (user_name,mobile,address,create_time,update_time ) VALUES ( ?,?,?,?,? )
ShardingSphere-SQL: Actual SQL: master :::INSERT INTO user (user_name,mobile,address,create_time,update_time ) VALUES ( ?,?,?,?,? )
5. 注意事项
5.1 Mysql主从复制:
写操作时,slave0,slave1的数据并不会自动同步master的更改,因为master,slave0,slave1是同一个Mysql实例中的三个不同数据库,彼此独立。要实现Mysql的主从复制,必须是不同的Mysql服务器和不同的数据库。因为Mysql复制是基于整个实例的,也就是说,通常主库的二进制日志会记录所有数据库的更改,而从库会复制整个实例的数据。
同一个Mysql服务器,不同数据库实现主从复制,可以使用触发器或者使用CDC工具(如Canal)实现同步。
5.2 负载均衡算法:
ShardingSphere支持多种负载均衡算法,如ROUND_ROBIN(轮询)、RANDOM(随机)等。可根据业务需求自定义负载均衡算法。
5.3 SQL日志
开启sql-show: true,便于调试和验证读写分离是否生效。
5.4 事务管理
读写分离场景下,事务中的读操作默认路由到主库,可通过配置调整 。
6. 总结
通过ShardingSphere的读写分离功能,可以轻松实现数据库的读写分离,提升系统的读取性能。配置简单,且与主流ORM框架(如MyBatis-Plus)无缝集成。在实际应用中,需根据业务需求选择合适的负载均衡算法,并确保数据同步机制的正确性。