Sharding Sphere ~ Sharding-jdbc分库分表、读写分离

Sharding Sphere 是什么?

1、一套开源的分布式数据库中间件解决方案
2、有三个产品:Sharding-JDBC 和 Sharding-Proxy
3、定位为关系型数据库中间件,合理在分布式环境下使用关系型数据库操作

如何学习?

官网: http://shardingsphere.apache.org/
版本: 4.0
在这里插入图片描述
在这里插入图片描述
官方文档对每个产品的描述非常详细,建议大家都去看看。所有的配置都不需要记忆,全部从官方文档中找
这里我选择的版本是4.0版本,配置方式的话,直接使用springboot项目咯,简化配置
若spring项目,参考文档即可

Sharding jdbc

在这里插入图片描述

Sharding-jdbc 入门案例

若是初学的,想入门的,不建议看这篇文件,强烈建议大家去看官方文档
这篇文章仅记录本人的自学,几个配置而已

  1. 基础项目搭建
    pom文件
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.11.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.dgut.edu.com</groupId>
    <artifactId>sharding_sphere_practive</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>sharding_sphere_practive</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
        </dependency>

        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.1.20</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>

        <dependency>
            <groupId>org.apache.shardingsphere</groupId>
            <artifactId>sharding-jdbc-spring-boot-starter</artifactId>
            <version>4.0.0-RC1</version>
        </dependency>

        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.0.5</version>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>

    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

  1. 整合Mybatis-plus
@MapperScan("com.dgut.edu.com.shardingsphere.mapper")

在这里插入图片描述

入门案例1:水平分表

  1. 提供SQL
CREATE TABLE course_2(
    c_id BIGINT PRIMARY KEY AUTO_INCREMENT,
    course_name VARCHAR(256) DEFAULT NULL,
    u_id INT DEFAULT NULL,
    state SMALLINT DEFAULT NULL		
);

配置文件

## 指数据源信息
spring.shardingsphere.datasource.names=m1
# 一个实体类对应两张表,覆盖
spring.main.allow-bean-definition-overriding=true


## 配置数据源具体内容,包括连接池、驱动、地址、用户名和密码
spring.shardingsphere.datasource.m1.type=com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.m1.driver-class-name=com.mysql.cj.jdbc.Driver
spring.shardingsphere.datasource.m1.url=jdbc:mysql://localhost:3306/course_db?serverTimezone=GMT%2B8
spring.shardingsphere.datasource.m1.username=root
spring.shardingsphere.datasource.m1.password=root


## 配置course表标准分片表配置:配置表在哪个数据库里面,表明是什么
#spring.shardingsphere.sharding.tables.course.actual-data-nodes=m1.course_$->{
    
    1..2}
spring.shardingsphere.sharding.tables.course.actual-data-nodes=m1.course_1,m1.course_2

## 指定 course表里面的主键cId生成策略
spring.shardingsphere.sharding.tables.course.key-generator.column=c_id
spring.shardingsphere.sharding.tables.course.key-generator.type=SNOWFLAKE

## 指定分片策略,约定若c_id值为偶数,则添加到course_2, 若c_id的值为奇数,则添加到course_1
spring.shardingsphere.sharding.tables.course.table-strategy.inline.sharding-column=c_id
spring.shardingsphere.sharding.tables.course.table-strategy.inline.algorithm-expression=course_$->{
    
    c_id % 2 + 1}

## 打印执行sql
spring.shardingsphere.props.sql.show=true

## 启用驼峰命名
mybatis-plus.configuration.map-underscore-to-camel-case=true

测试用例

package com.dgut.edu.com.shardingsphere.mapper;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.dgut.edu.com.shardingsphere.domain.Course;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

/**
 * @author xiaozheng
 * @version 1.0
 * @date 2020/11/11 14:28
 */
@SpringBootTest
public class CourseTest水平分表 {
    
    
	@Autowired
	private CourseMapper courseMapper;

	@Test
	public void testInit(){
    
    
		System.out.println("testInit..........................");
	}

	//======================测试水平分表=====================
	/**
	 * 添加课程
	 */
	@Test
	public void addCourse() {
    
    
		for(int i = 1; i <= 10; i++) {
    
    
			Course course = new Course();
			course.setCourseName("java"+i);
			course.setState(i);
			courseMapper.insert(course);
		}
	}

	//======================测试水平分表=====================
	// 查询课程方法
	@Test
	public void findCourse(){
    
    
		QueryWrapper<Course> queryWrapper = new QueryWrapper<>();
		queryWrapper.eq("c_id", 533313900888719361l);
		Course course = courseMapper.selectOne(queryWrapper);
		System.out.println(course.toString());
	}
}

水平分库

配置文件

## 指数据源信息
spring.shardingsphere.datasource.names=m1,m2
# 一个实体类对应两张表,覆盖
spring.main.allow-bean-definition-overriding=true


## 配置数据源具体内容,包括连接池、驱动、地址、用户名和密码
spring.shardingsphere.datasource.m1.type=com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.m1.driver-class-name=com.mysql.cj.jdbc.Driver
spring.shardingsphere.datasource.m1.url=jdbc:mysql://localhost:3306/edu_db_1?serverTimezone=GMT%2B8
spring.shardingsphere.datasource.m1.username=root
spring.shardingsphere.datasource.m1.password=root

spring.shardingsphere.datasource.m2.type=com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.m2.driver-class-name=com.mysql.cj.jdbc.Driver
spring.shardingsphere.datasource.m2.url=jdbc:mysql://localhost:3306/edu_db_2?serverTimezone=GMT%2B8
spring.shardingsphere.datasource.m2.username=root
spring.shardingsphere.datasource.m2.password=root


## 配置course表标准分片表配置:配置表在哪个数据库里面,表明是什么
spring.shardingsphere.sharding.tables.course.actual-data-nodes=m$->{
    
    1..2}.course_$->{
    
    1..2}

## 指定 course表里面的主键cId生成策略
spring.shardingsphere.sharding.tables.course.key-generator.column=c_id
spring.shardingsphere.sharding.tables.course.key-generator.type=SNOWFLAKE


## 指定分片策略,约定若c_id值为偶数,则添加到course_2, 若c_id的值为奇数,则添加到course_1
spring.shardingsphere.sharding.tables.course.table-strategy.inline.sharding-column=c_id
spring.shardingsphere.sharding.tables.course.table-strategy.inline.algorithm-expression=course_$->{
    
    c_id % 2 + 1}


## 指定分库策略,约定若user_id的值为偶数,则添加到m2, 若user_id的值为奇数,则添加到m1
spring.shardingsphere.sharding.tables.course.database-strategy.inline.sharding-column=u_id
spring.shardingsphere.sharding.tables.course.database-strategy.inline.algorithm-expression=m$->{
    
    u_id % 2 + 1}


## 打印执行sql
spring.shardingsphere.props.sql.show=true

## 启用驼峰命名
mybatis-plus.configuration.map-underscore-to-camel-case=true

测试用例

package com.dgut.edu.com.shardingsphere.mapper;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.dgut.edu.com.shardingsphere.domain.Course;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

/**
 * @author xiaozheng
 * @version 1.0
 * @date 2020/11/11 14:28
 */
@SpringBootTest
public class CourseTest水平分库 {
    
    
	@Autowired
	private CourseMapper courseMapper;

	@Test
	public void testInit(){
    
    
		System.out.println("testInit..........................");
	}
	//======================测试水平分库=====================
	/**
	 * 添加课程
	 */
	@Test
	public void addCourse() {
    
    
		for(int i = 1; i <= 1; i++) {
    
    
			Course course = new Course();
			course.setCourseName("java" + i);
			course.setUId(100 + i);
			course.setState(i);
			courseMapper.insert(course);
		}
	}
	//======================测试水平分库=====================
	// 查询课程方法
	@Test
	public void findCourse(){
    
    
		QueryWrapper<Course> queryWrapper = new QueryWrapper<>();
		queryWrapper.eq("c_id", 533313900888719361l);
		Course course = courseMapper.selectOne(queryWrapper);
		System.out.println(course.toString());
	}
}

垂直分库

Mysql

CREATE TABLE t_user(
    user_id BIGINT PRIMARY KEY,
    username VARCHAR(256) DEFAULT NULL,
    ustatus VARCHAR(256)
);


配置文件

## 指数据源信息
spring.shardingsphere.datasource.names=m1,m2,m0
# 一个实体类对应两张表,覆盖
spring.main.allow-bean-definition-overriding=true


## 配置数据源具体内容,包括连接池、驱动、地址、用户名和密码
spring.shardingsphere.datasource.m1.type=com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.m1.driver-class-name=com.mysql.cj.jdbc.Driver
spring.shardingsphere.datasource.m1.url=jdbc:mysql://localhost:3306/edu_db_1?serverTimezone=GMT%2B8
spring.shardingsphere.datasource.m1.username=root
spring.shardingsphere.datasource.m1.password=root

spring.shardingsphere.datasource.m2.type=com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.m2.driver-class-name=com.mysql.cj.jdbc.Driver
spring.shardingsphere.datasource.m2.url=jdbc:mysql://localhost:3306/edu_db_2?serverTimezone=GMT%2B8
spring.shardingsphere.datasource.m2.username=root
spring.shardingsphere.datasource.m2.password=root

spring.shardingsphere.datasource.m0.type=com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.m0.driver-class-name=com.mysql.cj.jdbc.Driver
spring.shardingsphere.datasource.m0.url=jdbc:mysql://localhost:3306/user_db?serverTimezone=GMT%2B8
spring.shardingsphere.datasource.m0.username=root
spring.shardingsphere.datasource.m0.password=root


## 配置course表标准分片表配置:配置表在哪个数据库里面,表明是什么
spring.shardingsphere.sharding.tables.course.actual-data-nodes=m$->{
    
    1..2}.course_$->{
    
    1..2}

## 配置user表标准分片表配置,配置表在哪个数据库里面,表名是什么
spring.shardingsphere.sharding.tables.user.actual-data-nodes=m$->{
    
    0}.t_user

## 指定 course表里面的主键cId生成策略
spring.shardingsphere.sharding.tables.course.key-generator.column=c_id
spring.shardingsphere.sharding.tables.course.key-generator.type=SNOWFLAKE

## 指定 user表里面的主键cId生成策略
spring.shardingsphere.sharding.tables.user.key-generator.column=user_id
spring.shardingsphere.sharding.tables.user.key-generator.type=SNOWFLAKE


## 指定分片策略,约定若c_id值为偶数,则添加到course_2, 若c_id的值为奇数,则添加到course_1
spring.shardingsphere.sharding.tables.course.table-strategy.inline.sharding-column=c_id
spring.shardingsphere.sharding.tables.course.table-strategy.inline.algorithm-expression=course_$->{
    
    c_id % 2 + 1}

spring.shardingsphere.sharding.tables.user.table-strategy.inline.sharding-column=user_id
spring.shardingsphere.sharding.tables.user.table-strategy.inline.algorithm-expression=t_user


## 指定分库策略,约定若user_id的值为偶数,则添加到m2, 若user_id的值为奇数,则添加到m1
spring.shardingsphere.sharding.tables.course.database-strategy.inline.sharding-column=u_id
spring.shardingsphere.sharding.tables.course.database-strategy.inline.algorithm-expression=m$->{
    
    u_id % 2 + 1}


## 打印执行sql
spring.shardingsphere.props.sql.show=true

## 启用驼峰命名
mybatis-plus.configuration.map-underscore-to-camel-case=true

测试用例

package com.dgut.edu.com.shardingsphere.mapper;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.dgut.edu.com.shardingsphere.domain.Course;
import com.dgut.edu.com.shardingsphere.domain.User;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

/**
 * @author xiaozheng
 * @version 1.0
 * @date 2020/11/11 14:28
 */
@SpringBootTest
public class CourseTest垂直分库 {
    
    
	@Autowired
	private CourseMapper courseMapper;
	@Autowired
	private UserMapper userMapper;

	@Test
	public void testInit(){
    
    
		System.out.println("testInit..........................");
	}

	//======================测试垂直分库==================

	/**
	 * 添加课程
	 */
	@Test
	public void addUserDb() {
    
    
		for(int i = 1; i <= 1; i++) {
    
    
			User user = new User();
			user.setUsername("xiaozheng" + i);
			user.setUstatus(String.valueOf(i));
			userMapper.insert(user);
		}
	}

	// 查询课程方法
	@Test
	public void findCourse(){
    
    
		QueryWrapper<Course> queryWrapper = new QueryWrapper<>();
		queryWrapper.eq("c_id", 1326442033304387586l);
		Course course = courseMapper.selectOne(queryWrapper);
		System.out.println(course.toString());
	}


}

操作公共表

CREATE TABLE `common_dictionary` (
  `d_id` bigint(20) NOT NULL,
  `d_name` varchar(256) DEFAULT NULL,
  PRIMARY KEY (`d_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

配置


# 配置公共表
spring.shardingsphere.sharding.broadcast-tables=common_dictionary 
spring.shardingsphere.sharding.tables.t_udict.key-generator.column=d_id 
spring.shardingsphere.sharding.tables.t_udict.key-generator.type=SNOWFLAKE

读写分离

## 指数据源信息
spring.shardingsphere.datasource.names=m1,m2,m0,s0
# 一个实体类对应两张表,覆盖
spring.main.allow-bean-definition-overriding=true


## 配置数据源具体内容,包括连接池、驱动、地址、用户名和密码
spring.shardingsphere.datasource.m1.type=com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.m1.driver-class-name=com.mysql.cj.jdbc.Driver
spring.shardingsphere.datasource.m1.url=jdbc:mysql://localhost:3306/edu_db_1?serverTimezone=GMT%2B8
spring.shardingsphere.datasource.m1.username=root
spring.shardingsphere.datasource.m1.password=root

spring.shardingsphere.datasource.m2.type=com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.m2.driver-class-name=com.mysql.cj.jdbc.Driver
spring.shardingsphere.datasource.m2.url=jdbc:mysql://localhost:3306/edu_db_2?serverTimezone=GMT%2B8
spring.shardingsphere.datasource.m2.username=root
spring.shardingsphere.datasource.m2.password=root

spring.shardingsphere.datasource.m0.type=com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.m0.driver-class-name=com.mysql.cj.jdbc.Driver
spring.shardingsphere.datasource.m0.url=jdbc:mysql://localhost:3306/user_db?serverTimezone=GMT%2B8
spring.shardingsphere.datasource.m0.username=root
spring.shardingsphere.datasource.m0.password=root

# user_db 从服务器
spring.shardingsphere.datasource.s0.type=com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.s0.driver-class-name=com.mysql.cj.jdbc.Driver
spring.shardingsphere.datasource.s0.url=jdbc:mysql://localhost:3307/user_db?serverTimezone=GMT%2B8
spring.shardingsphere.datasource.s0.username=root
spring.shardingsphere.datasource.s0.password=root


## 配置course表标准分片表配置:配置表在哪个数据库里面,表明是什么
spring.shardingsphere.sharding.tables.course.actual-data-nodes=m$->{
    
    1..2}.course_$->{
    
    1..2}

## 配置user表标准分片表配置,配置表在哪个数据库里面,表名是什么
#spring.shardingsphere.sharding.tables.user.actual-data-nodes=m$->{
    
    0}.t_user
spring.shardingsphere.sharding.tables.user.actual-data-nodes=ds0.t_user

## 指定 course表里面的主键cId生成策略
spring.shardingsphere.sharding.tables.course.key-generator.column=c_id
spring.shardingsphere.sharding.tables.course.key-generator.type=SNOWFLAKE

## 指定 user表里面的主键cId生成策略
spring.shardingsphere.sharding.tables.user.key-generator.column=user_id
spring.shardingsphere.sharding.tables.user.key-generator.type=SNOWFLAKE


## 指定分片策略,约定若c_id值为偶数,则添加到course_2, 若c_id的值为奇数,则添加到course_1
spring.shardingsphere.sharding.tables.course.table-strategy.inline.sharding-column=c_id
spring.shardingsphere.sharding.tables.course.table-strategy.inline.algorithm-expression=course_$->{
    
    c_id % 2 + 1}

spring.shardingsphere.sharding.tables.user.table-strategy.inline.sharding-column=user_id
spring.shardingsphere.sharding.tables.user.table-strategy.inline.algorithm-expression=t_user


## 指定分库策略,约定若user_id的值为偶数,则添加到m2, 若user_id的值为奇数,则添加到m1
spring.shardingsphere.sharding.tables.course.database-strategy.inline.sharding-column=u_id
spring.shardingsphere.sharding.tables.course.database-strategy.inline.algorithm-expression=m$->{
    
    u_id % 2 + 1}


# 主库从库逻辑数据源定义 ds0为user_db
spring.shardingsphere.sharding.master-slave-rules.ds0.master-data-source-name=m0
spring.shardingsphere.sharding.master-slave-rules.ds0.slave-data-source-names=s0



# 配置公共表
spring.shardingsphere.sharding.broadcast-tables=common_dictionary 
spring.shardingsphere.sharding.tables.t_udict.key-generator.column=d_id 
spring.shardingsphere.sharding.tables.t_udict.key-generator.type=SNOWFLAKE


## 打印执行sql
spring.shardingsphere.props.sql.show=true

## 启用驼峰命名
mybatis-plus.configuration.map-underscore-to-camel-case=true

测试用例

package com.dgut.edu.com.shardingsphere.mapper;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.dgut.edu.com.shardingsphere.domain.Course;
import com.dgut.edu.com.shardingsphere.domain.User;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

/**
 * @author xiaozheng
 * @version 1.0
 * @date 2020/11/11 14:28
 */
@SpringBootTest
public class CourseTest{
    
    
	@Autowired
	private CourseMapper courseMapper;
	@Autowired
	private UserMapper userMapper;

	@Test
	public void testInit(){
    
    
		System.out.println("testInit..........................");
	}

	//======================测试垂直分库==================

	/**
	 * 添加课程
	 */
	@Test
	public void addUserDb() {
    
    
		for(int i = 1; i <= 2; i++) {
    
    
			User user = new User();
			user.setUsername("xiaozheng" + i);
			user.setUstatus(String.valueOf(i));
			userMapper.insert(user);
		}
	}

	@Test
	public void findUserDb() {
    
    
		QueryWrapper<User> queryWrapper = new QueryWrapper<>();
		queryWrapper.eq("user_id", 1326801196324855810l);
		User user = userMapper.selectOne(queryWrapper);
		System.out.println(user.toString());
	}


	// 查询课程方法
	@Test
	public void findCourse(){
    
    
		QueryWrapper<Course> queryWrapper = new QueryWrapper<>();
		queryWrapper.eq("c_id", 1326801196324855810l);
		Course course = courseMapper.selectOne(queryWrapper);
		System.out.println(course.toString());
	}


}

如何部署读写分离mysql架构

click me 学习

猜你喜欢

转载自blog.csdn.net/xiaozhegaa/article/details/109678957