Sharding-Jdbc实现读写分离

Sharding-Jdbc实现读写分离

文章目录

    • Sharding-Jdbc实现读写分离
      • 简单了解
      • Sharding-Jdbc与Mycat的区别
        • 不同点
          • mycat
          • Sharding-JDBC
        • ShardingShpere其他产品
      • spring-jdbc 读写分离
        • 实现读写分离原理
      • 简单实现
        • 搭建环境
        • maven
        • yml配置
        • 配置文件

简单了解

Sharding-JDBC是ShardingSphere的第一个产品,ShardingSphere是一套开源的分布式数据库中间件解决方案组成的生态圈,它包含sharding-JDBC、Sharding-Proxy和Sharding-Sidecar。目前Sharding-Sidecar还在开发中。

官网连接

Sharding-Jdbc与Mycat的区别

Mycat是第三方应用中间件数据库代理框架,Mycat拦截客户端所有的Jdbc请求,同一转发到真实的数据库。

Sharding-Jdbc是一个Jar形式,在本地应用成重写Jdbc原生的方法,实现数据库分片形式。

和微服务中学习的SpringCloud Ribbon与Nginx实现负载均衡区别一样。

GitHub对比

应用名 star fork
shardingsphere 9.6K 3.3K
Mycat 7.5K 3.6K

Sharding-Jdbc实现读写分离_第1张图片

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语句,所以返回的是连接从数据库的连接。

Sharding-Jdbc实现读写分离_第2张图片

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

        
        <dependency>
            <groupId>io.shardingjdbcgroupId>
            <artifactId>sharding-jdbc-coreartifactId>
            <version>2.0.3version>
        dependency>
        
        <dependency>
            <groupId>com.alibabagroupId>
            <artifactId>druid-spring-boot-starterartifactId>
            <version>1.1.16version>
        dependency>
         <dependency>
            <groupId>mysqlgroupId>
            <artifactId>mysql-connector-javaartifactId>
            <scope>runtimescope>
        dependency>
        
        <dependency>
            <groupId>org.mybatis.spring.bootgroupId>
            <artifactId>mybatis-spring-boot-starterartifactId>
            <version>2.0.0version>
        dependency>
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starterartifactId>
        dependency>
        
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-webartifactId>
        dependency>
        <dependency>
            <groupId>org.projectlombokgroupId>
            <artifactId>lombokartifactId>
            <optional>trueoptional>
        dependency>

yml配置

#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
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<String, HikariDataSource> dataSources = new HashMap<>();

    private MasterSlaveRuleConfiguration masterSlaveRule;

}

  • MybatisMapperScannerConfig.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<String, DataSource> dataSourceMap = Maps.newHashMap();
        dataSourceMap.putAll(shardingMasterSlaveConfig.getDataSources());
        final Map<String, Object> newHashMap = Maps.newHashMap();
        // 创建 MasterSlave数据源
        DataSource dataSource = MasterSlaveDataSourceFactory.createDataSource(dataSourceMap,
                shardingMasterSlaveConfig.getMasterSlaveRule(), newHashMap);
//        log.info("masterSlaveDataSource config complete");
        return dataSource;
    }

 
}

以上的代码是主要的配置代码,其他的业务代码就没有放上去

你可能感兴趣的:(Sharding-Jdbc实现读写分离)