携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第15天,点击查看活动详情
概述
前面的文章中也有提到读写分离的方案,并且通过自己管理项目中的多数据源+注解的方式实现了读写分离,自己实现读写分离的功能可以理解为是一个帮助理解方案的一个思想,或者是读写分离中间件的一个实现缩影。
之后将采用Apache的顶级开源项目ShardingSphere的sharding-jdbc组件作为项目中的多数据源管理,实现读写分离、数据分片、读写分离+数据分片的方案。
ShardingSphere读写分离
同一时刻有大量并发读操作和较少写操作类型的应用系统来说,将数据库拆分为主库和从库,主库负责处理事务性的增删改操作,从库负责处理查询操作,能够有效的避免由数据更新导致的行锁,使得整个系统的查询性能得到极大的改善。
与将数据根据分片键打散至各个数据节点的水平分片不同,读写分离则是根据SQL语义的分析,将读操作和写操作分别路由至主库与从库
-
主库: 添加、更新以及删除数据操作所使用的数据库,目前仅支持单主库。
-
从库: 查询数据操作所使用的数据库,可支持多从库。
-
主从同步: 将主库的数据异步的同步到从库的操作。由于主从同步的异步性,从库与主库的数据会短时间内不一致。
-
负载均衡策略: 通过负载均衡策略将查询请求疏导至不同从库。
核心功能:
- 提供一主多从的读写分离配置,可独立使用,也可配合分库分表使用。
- 独立使用读写分离支持SQL透传。
- 同一线程且同一数据库连接内,如有写入操作,以后的读操作均从主库读取,用于保证数据一致性。
- 基于Hint的强制主库路由。
环境说明
- Spring boot 2.5.3
- Druid 1.1.22
- mybatis-plus 3.4.3
- ShardingSphere 4.1.1
- MySQL 5.7.27
读写分离配置
- 引入依赖
<!-- sharding-jdbc for spring boot 4.1.1 -->
<dependency>
<groupId>org.apache.shardingsphere</groupId>
<artifactId>sharding-jdbc-spring-boot-starter</artifactId>
<version>${sharding-sphere.version}</version>
</dependency>
- 添加数据源配置文件 需要删除掉单库单表的数据源配置信息。
spring.shardingsphere.datasource.names=ds0,ds1,ds2
spring.shardingsphere.datasource.ds0.type=com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.ds0.driver-class-name=com.mysql.cj.jdbc.Driver
spring.shardingsphere.datasource.ds0.url=jdbc:mysql://xxx.xxx.xxx.xxx:3306/monomer_order?useUnicode=true&characterEncoding=utf8&useSSL=false&autoReconnect=true&zeroDateTimeBehavior=convertToNull
spring.shardingsphere.datasource.ds0.username=root
spring.shardingsphere.datasource.ds0.password=xxx
spring.shardingsphere.datasource.ds1.type=com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.ds1.driver-class-name=com.mysql.cj.jdbc.Driver
spring.shardingsphere.datasource.ds1.url=jdbc:mysql://xxx.xxx.xxx.xxx:3306/monomer_order?useUnicode=true&characterEncoding=utf8&useSSL=false&autoReconnect=true&zeroDateTimeBehavior=convertToNull
spring.shardingsphere.datasource.ds1.username=root
spring.shardingsphere.datasource.ds1.password=xxx
spring.shardingsphere.datasource.ds2.type=com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.ds2.driver-class-name=com.mysql.cj.jdbc.Driver
spring.shardingsphere.datasource.ds2.url=jdbc:mysql://xxx.xxx.xxx.xxx:3306/monomer_order?useUnicode=true&characterEncoding=utf8&useSSL=false&autoReconnect=true&zeroDateTimeBehavior=convertToNull
spring.shardingsphere.datasource.ds2.username=root
spring.shardingsphere.datasource.ds2.password=xxx
spring.shardingsphere.masterslave.name=ms
spring.shardingsphere.masterslave.master-data-source-name=ds0
spring.shardingsphere.masterslave.slave-data-source-names=ds1,ds2
spring.shardingsphere.masterslave.load-balance-algorithm-type=round_robin
spring.shardingsphere.props.sql.show=true
- 过滤掉默认数据源
主要是过滤掉DruidDataSourceAutoConfigure.class、DataSourceAutoConfiguration.class
@SpringBootApplication(exclude = {DruidDataSourceAutoConfigure.class, DataSourceAutoConfiguration.class})
public class OrderApplication {
public static void main(String[] args) {
SpringApplication.run(OrderApplication.class, args);
}
}
其他的dao、mapper与单库单表的写法一致,不用进行修改。
启动项目
2022-08-09 17:55:59.373 INFO 1012 --- [ main] com.alibaba.druid.pool.DruidDataSource : {dataSource-1} inited
2022-08-09 17:55:59.595 INFO 1012 --- [ main] com.alibaba.druid.pool.DruidDataSource : {dataSource-2} inited
2022-08-09 17:55:59.760 INFO 1012 --- [ main] com.alibaba.druid.pool.DruidDataSource : {dataSource-3} inited
2022-08-09 17:55:59.981 INFO 1012 --- [ main] o.a.s.core.log.ConfigurationLogger : MasterSlaveRuleConfiguration:
loadBalanceAlgorithmType: round_robin
masterDataSourceName: ds0
name: ms
slaveDataSourceNames:
- ds1
- ds2
2022-08-09 17:55:59.983 INFO 1012 --- [ main] o.a.s.core.log.ConfigurationLogger : Properties:
sql.show: 'true'
可以看到项目启动的时候初始化了配置的所有数据源信息,读取了主从配置到MasterSlaveRuleConfiguration类中,其他的属性信息读取到了Properties中。
添加数据
查询数据
- 第一次查询
- 第二次查询