需求说明
-
读写分离
数据库做读写分离,一主多从
解决方案
-
应用层解决
-
中间件解决
Sharding-JDBC
Sharding-JDBC
-
官网地址
https://shardingsphere.apache.org/document/current/en/overview/
-
简介
Sharding-JDBC定位为轻量级Java框架,在Java的JDBC层提供的额外服务。 它使用客户端直连数据库,以jar包形式提供服务,无需额外部署和依赖,可理解为增强版的JDBC驱动,完全兼容JDBC和各种ORM框架
-
特性
-
适用于任何基于Java的ORM框架,如:JPA, Hibernate, Mybatis, Spring JDBC Template或直接使用JDBC
-
基于任何第三方的数据库连接池,如:DBCP, C3P0, BoneCP, Druid, HikariCP等。
-
支持任意实现JDBC规范的数据库。目前支持MySQL,Oracle,SQLServer和PostgreSQL。
-
-
调用流程
-
其他
ShardingSphere是一套开源的分布式数据库中间件解决方案组成的生态圈,它由Sharding-JDBC、Sharding-Proxy和Sharding-Sidecar(计划中)这3款相互独立的产品组成。 他们均提供标准化的数据分片、分布式事务和数据库治理功能,可适用于如Java同构、异构语言、容器、云原生等各种多样化的应用场景。
实现步骤
MySQL主从复制环境搭建
-
参考链接
https://blog.csdn.net/weixin_42586723/article/details/107752844
数据库创建
-
SQL语句
分别在主从环境创建数据库mbank ,并在主节点mbank库中创建一个user表(此时会在从节点mbank库中自动创建user表),用于数据操作演示
CREATE DATABASE IF NOT EXISTS mbank DEFAULT CHARSET utf8 COLLATE utf8_general_ci; USE mbank; DROP TABLE IF EXISTS `user`; CREATE TABLE `user`( id bigint(64) not null, city varchar(20) not null, name varchar(20) not null, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Maven项目搭建
-
模块名称
sjdbc-read-write-springboot -
pom依赖
<!-- Sharding-JDBC --> <dependency> <groupId>org.apache.shardingsphere</groupId> <artifactId>sharding-jdbc-spring-boot-starter</artifactId> <version>4.0.0-RC1</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>2.0.1</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid-spring-boot-starter</artifactId> <version>1.1.16</version> </dependency>
数据源配置
-
application配置
server.port=8084 mybatis.config-location=classpath:META-INF/mybatis-config.xml # 数据源名称集合,对应下面数据源配置的名称 spring.shardingsphere.datasource.names=master,slave # 主数据源 spring.shardingsphere.datasource.master.type=com.alibaba.druid.pool.DruidDataSource spring.shardingsphere.datasource.master.driver-class-name=com.mysql.jdbc.Driver spring.shardingsphere.datasource.master.url=jdbc:mysql://192.168.159.134:3306/mbank?characterEncoding=utf-8 spring.shardingsphere.datasource.master.username=root spring.shardingsphere.datasource.master.password=1q2w3e4r # 从数据源 spring.shardingsphere.datasource.slave.type=com.alibaba.druid.pool.DruidDataSource spring.shardingsphere.datasource.slave.driver-class-name=com.mysql.jdbc.Driver spring.shardingsphere.datasource.slave.url=jdbc:mysql://192.168.159.133:3306/mbank?characterEncoding=utf-8 spring.shardingsphere.datasource.slave.username=root spring.shardingsphere.datasource.slave.password=123456 # 读写分离配置 load-balance-algorithm-type用于配置从库负载均衡算法类型,可选值:ROUND_ROBIN(轮询),RANDOM(随机) spring.shardingsphere.masterslave.load-balance-algorithm-type=round_robin # 最终的数据源名称 spring.shardingsphere.masterslave.name=dataSource # 主库数据源名称 spring.shardingsphere.masterslave.master-data-source-name=master # 从库数据源名称列表,多个逗号分割 spring.shardingsphere.masterslave.slave-data-source-names=slave # 显示SQL spring.shardingsphere.props.sql.show=true
测试样例
-
测试请求
- 发送请求
# 请求新增 http://localhost:8084/add # 查询列表 http://localhost:8084/users
- 查看数据库
-- 从库中执行发现已自动新增数据 select * from user; -- 在从库中执行新增脚本,并测试查询列表请求,发现存在刚通过脚本新增的数据
总结
存在问题
-
读延迟问题
问题阐述
系统刚插入一条数据,无法立即读取。因为主节点写入完之后数据是要复制给从节点的,读不到的原因是复制的时间比较长,也就是说数据还没复制到从节点,这时无法读取
解决方案
mysql5.7 的主从复制是多线程了,意味着速度会变快,但是不一定能保证百分百马上读取到
- 强制走主库查询
若业务层要求必须实时读取,那么可以通过Sharding-JDBC配置强制走主库进行读取 ```java public List<User> list() { // 强制路由主库 HintManager.getInstance().setMasterRouteOnly(); return userRepository.list(); } ```
-
数据同步
测试代码样例中并不涉及Mysql数据库之间复制,需要另外搭建主从复制的数据库。
参考地址
-
项目源码地址
https://github.com/yinjihuan/sharding-jdbc
-
在IDEA里导入从Github上下载的Maven项目
https://blog.csdn.net/sikefeng/article/details/80044693
-
Sharding-JDBC:查询量大如何优化
https://www.cnblogs.com/yinjihuan/p/10965595.html
-
java读写分离的实现
https://www.cnblogs.com/ngy0217/p/8987508.html
https://www.cnblogs.com/ningwuyu/p/12091855.html
-
MySQL主从复制
https://www.jianshu.com/p/19cb0f16dea4