Sharding-Jdbc实现读写分离 2020-01-05 程序之旅 暂无评论 2134 次阅读 ## Sharding-Jdbc实现读写分离 [TOC] ### 简单了解 Sharding-JDBC是ShardingSphere的第一个产品,ShardingSphere是一套开源的分布式数据库中间件解决方案组成的生态圈,它包含sharding-JDBC、Sharding-Proxy和Sharding-Sidecar。目前Sharding-Sidecar还在开发中。 [官网连接](https://shardingsphere.apache.org/index_zh.html) ### Sharding-Jdbc与Mycat的区别 Mycat是第三方应用中间件数据库代理框架,Mycat拦截客户端所有的Jdbc请求,同一转发到真实的数据库。 Sharding-Jdbc是一个Jar形式,在本地应用成重写Jdbc原生的方法,实现数据库分片形式。 > 和微服务中学习的SpringCloud Ribbon与Nginx实现负载均衡区别一样。 **GitHub对比** | 应用名 | star | fork | | ------------------------------------------------------------ | ---- | ---- | | [shardingsphere](https://github.com/apache/incubator-shardingsphere) | 9.6K | 3.3K | | [Mycat](https://github.com/MyCATApache/Mycat-Server) | 7.5K | 3.6K | ![sharding-jdbc.png](https://mufeng-blog.oss-cn-beijing.aliyuncs.com/typecho/2020/01/05/337963108546922/sharding-jdbc.png) ![mycat.png](https://mufeng-blog.oss-cn-beijing.aliyuncs.com/typecho/2020/01/05/337952938295224/mycat.png) #### 不同点 ##### mycat - 支持NoSQL技术 - 有web控制页面 - 数据库proxy中间件 - xml文件配置 ##### Sharding-JDBC - 配置动态化 - 应用层组件集成 - java、yaml或spring boot配置 #### ShardingShpere其他产品 | *Sharding-JDBC* | *Sharding-Proxy* | *Sharding-Sidecar* | | | :-------------- | :--------------- | :----------------- | ---------------- | | 数据库 | `任意` | MySQL/PostgreSQL | MySQL/PostgreSQL | | 连接消耗数 | `高` | 低 | 高 | | 异构语言 | `仅Java` | 任意 | 任意 | | 性能 | `损耗低` | 损耗略高 | 损耗低 | | 无中心化 | `是` | 否 | 是 | | 静态入口 | `无` | 有 | 无 | ### spring-jdbc 读写分离 #### 实现读写分离原理 1. 需要在配置文件配置读写分离jdbc连接全部交给Sharding-Jdbc。 2. Sharding-Jdbc会自动判断sql语句类型(DML或者DQL),如果是DML语句的话,会获取主数据库的jdbc连接配置进行发送请求,如果是DQL语句的话,获取从数据库的jdbc连接发送请求。 **查看源码** 在`MasterSlaveDataSource.class`可以查到获取数据库连接的方法,这里调用的DQL语句,所以返回的是连接从数据库的连接。 ![image-20200105215342151.png](https://mufeng-blog.oss-cn-beijing.aliyuncs.com/typecho/2020/01/05/337943098011219/image-20200105215342151.png) > SQL语言共分为四大类:数据查询语言DQL,数据操纵语言DML,数据定义语言DDL,数据控制语言DCL。 > >1. 数据查询语言DQL,基本结构是由SELECT子句,FROM子句,WHERE。 >2. 数据操纵语言DML,有三种形式:insert、update、delete。 >3. 数据定义语言DDL, 用来创建数据库中的各种对象-----表、视图、索引、同义词、聚簇等 。 >4. 数据控制语言DCL, 用来授予或回收访问数据库的某种特权,并控制数据库操纵事务发生的时间及效果,对数据库实行监视等 ### 简单实现 > 这里使用sharding-jdbc实现读写分离,前提是要先实现数据库的主从复制。 #### 搭建环境 - spring boot 2.2.2 - mysql 5.7 - sharding-jdbc 2.0.3 - mybatis - druid #### maven ```xml io.shardingjdbc sharding-jdbc-core 2.0.3 com.alibaba druid-spring-boot-starter 1.1.16 mysql mysql-connector-java runtime org.mybatis.spring.boot mybatis-spring-boot-starter 2.0.0 org.springframework.boot spring-boot-starter org.springframework.boot spring-boot-starter-web org.projectlombok lombok true ``` #### yml配置 ```yaml #shardingjdbc配置 sharding: jdbc: data-sources: ## 配置从数据库 ds_slave_0: type: com.alibaba.druid.pool.DruidDataSource password: root username: root jdbc-url: jdbc:mysql://localhost:3306/test1?serverTimezone=Asia/Shanghai&characterEncoding=utf-8 driver-class-name: com.mysql.cj.jdbc.Driver ## 配置主数据库 ds_master: type: com.alibaba.druid.pool.DruidDataSource password: root username: root jdbc-url: jdbc:mysql://localhost:3306/test?serverTimezone=Asia/Shanghai&characterEncoding=utf-8 driver-class-name: com.mysql.cj.jdbc.Driver ## 配置读写分离 master-slave-rule: ## 配置从库选择策略,提供轮询与随机 load-balance-algorithm-type: round_robin slave-data-source-names: ds_slave_0 name: ds_ms master-data-source-name: ds_master ``` #### 配置文件 - ShardingMasterSlaveConfig.java ```java package com.felton.mybatismapper.config; import com.zaxxer.hikari.HikariDataSource; import io.shardingjdbc.core.api.config.MasterSlaveRuleConfiguration; import lombok.Data; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.Bean; import java.util.HashMap; import java.util.Map; /** * ShardingMasterSlaveConfig * * @author liurui * @Description: * @date 2020/1/5 */ @Data @ConfigurationProperties(prefix = "sharding.jdbc") public class ShardingMasterSlaveConfig { private Map dataSources = new HashMap<>(); private MasterSlaveRuleConfiguration masterSlaveRule; } ``` - MybatisMapperScannerConfig.java ```java package com.felton.mybatismapper.config; import com.felton.mybatismapper.baseDao.IBaseDao; import com.google.common.collect.Maps; import io.shardingjdbc.core.api.MasterSlaveDataSourceFactory; import io.shardingjdbc.core.jdbc.core.datasource.MasterSlaveDataSource; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.DependsOn; import tk.mybatis.spring.mapper.MapperScannerConfigurer; import javax.annotation.Resource; import javax.sql.DataSource; import java.sql.SQLException; import java.util.Map; import java.util.Properties; /** * MybatisMapperScannerConfig * * @author liurui * @Description: 通用mapper配置 * @date 2019/12/19 */ @Configuration @EnableConfigurationProperties(ShardingMasterSlaveConfig.class) @ConditionalOnProperty({ "sharding.jdbc.data-sources.ds_master.jdbc-url", "sharding.jdbc.master-slave-rule.master-data-source-name" }) public class MybatisMapperScannerConfig { // /*@Autowired private ShardingMasterSlaveConfig shardingMasterSlaveConfig*/; @Bean public DataSource masterSlaveDataSource(ShardingMasterSlaveConfig shardingMasterSlaveConfig) throws SQLException { final Map dataSourceMap = Maps.newHashMap(); dataSourceMap.putAll(shardingMasterSlaveConfig.getDataSources()); final Map newHashMap = Maps.newHashMap(); // 创建 MasterSlave数据源 DataSource dataSource = MasterSlaveDataSourceFactory.createDataSource(dataSourceMap, shardingMasterSlaveConfig.getMasterSlaveRule(), newHashMap); // log.info("masterSlaveDataSource config complete"); return dataSource; } } ``` > 以上的代码是主要的配置代码,其他的业务代码就没有放上去 打赏: 微信, 支付宝 标签: java, 读写分离, sharding-jdbc, 数据库 本作品采用 知识共享署名-相同方式共享 4.0 国际许可协议 进行许可。