Sharding-JDBC、Sharding-Proxy实现水平分库分表垂直分库分表读写分离

1、基本概念

1.1 什么是 Sharding Sphere

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

1.2 分库分表
1.2.1 概念

分库分表有两种方式:垂直切分和水平切分
垂直切分:垂直分表和垂直分库(表结构不同)
水平切分:水平分表和水平分库 (表结构相同)

垂直分表: 根据业务规则,或访问频次、是否大字段,将常用字段与不常用字段为为N个表

垂直分库: 根据业务规则,将不同模块的表分别放在不同数据库,库可以分布在不同服务器

水平分表: 根据表数据规则,将一个表得数据根据规则进行拆分成多个表(比如:分区,轮询,取模)

水平分库:根据表数据规则,将一个表的数据分到不同的库中,每个库只有这个表的部分数据

1.2.2 应用

(1)在数据库设计时候考虑垂直分库和垂直分表
(2)随着数据库数据量增加,不要马上考虑做水平切分,首先考虑缓存处理,读写分离,使用索引等等方式,如果这些方式不能根本解决问题了,再考虑做水平分库和水平分表

1.2.3 分库分表问题

(1)跨节点连接查询问题(分页、排序)
(2)多数据源管理问题

2. Sharding-JDBC

2.1 Sharding-JDBC简介

1)是轻量级的 java 框架,是增强版的 JDBC 驱动
2)主要目的是:简化对分库分表之后数据相关操作
Sharding-JDBC

2.2 sharding-jdbc-demo工程搭建
2.2.1 新建module sharding-jdbc-demo
2.2.2 改pom
 <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
            <version>2.2.1.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <version>2.2.1.RELEASE</version>
        </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>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>

记得引入spring-boot-starter-web依赖,否则项目启动成功后会自动关闭。

2.2.3 启动类和业务类
@SpringBootApplication
@MapperScan(basePackages = "com.atguigu.springcloud.mapper")
public class ShardingJDBCApplication {
    public static void main(String[] args) {
        SpringApplication.run(ShardingJDBCApplication.class,args);
    }
}
@Mapper
public interface CourseMapper extends BaseMapper<Course> {
}
@Data
public class Course {
    private String cstatus;
    private String cname;
    private Long cid;
    private Long userId;
}
2.2.4 测试类

注意:测试类的包路径要与启动类一致,否则无法注入bean

@RunWith(SpringRunner.class)
@SpringBootTest
public class ShardingjdbcdemoApplicationTests {
}

在这里插入图片描述

2.3 Sharding-JDBC 实现水平分表
2.3.1 改properties
# shardingjdbc 分片策略
# 配置数据源,给数据源起名称
spring.shardingsphere.datasource.names=m1
# 允许覆盖重名bean
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.jdbc.Driver
spring.shardingsphere.datasource.m1.url=jdbc:mysql://localhost:3306/course_db?useUnicode=true&characterEncoding=utf-8&useSSL=false
spring.shardingsphere.datasource.m1.username=root
spring.shardingsphere.datasource.m1.password=root

#指定 course 表分布情况,配置表在哪个数据库里面,表名称都是什么 m1.course_1 ,m1.course_2
spring.shardingsphere.sharding.tables.course.actual-data-nodes=m1.course_$->{1..2}
# 指定 course 表里面主键 cid 生成策略 SNOWFLAKE
spring.shardingsphere.sharding.tables.course.key-generator.column=cid
spring.shardingsphere.sharding.tables.course.key-generator.type=SNOWFLAKE
# 指定分片策略 约定 cid 值偶数添加到 course_1 表,如果 cid 是奇数添加到 course_2表
spring.shardingsphere.sharding.tables.course.table-strategy.inline.sharding_column=cid
spring.shardingsphere.sharding.tables.course.table-strategy.inline.algorithm_expression=course_$->{cid % 2 + 1}
# 打开 sql 输出日志
spring.shardingsphere.props.sql.show=true

注意:mysql 5.8 版本驱动类与之前不同。我使用的是5.7的mysql.Driver的实现类的全路径名是com.mysql.jdbc.Driver。
在这里插入图片描述允许覆盖重名bean:dataSource这个bean已存在,允许覆盖。
spring.main.allow-bean-definition-overriding=true

cid % 2 + 1:为何+1?
+1的原因:如果下标从0开始就不用加,现在下标是从1开始,所以得加。本来下标0代表偶数,+1后下标1代表偶数

2.3.2 按照水平分表的方式,创建数据库和数据库表

1)创建数据库 course_db
2)在数据库创建两张表 course_1 和 course_2
3)约定规则:如果添加课程 id 是偶数把数据添加 course_1,如果奇数添加到 course_2

2.3.3 测试
//注入 mapper
    @Resource
    private CourseMapper courseMapper;

    //添加课程的方法
    @Test
    public void addCourse() {
        for (int i = 1; i <= 10; i++) {
            Course course = new Course();
            course.setCname("java" + i);
            course.setUserId(100L);
            course.setCstatus("Normal" + i);
            courseMapper.insert(course);
        }
    }

    //查询课程的方法
    @Test
    public void findCourse() {
        QueryWrapper<Course> wrapper = new QueryWrapper<>();
        wrapper.eq("cid", 763102447882207233L);
        Course course = courseMapper.selectOne(wrapper);
        System.out.println(course);
    }

2表cid全是奇数
在这里插入图片描述

2.4 Sharding-JDBC 实现水平分库
2.4.1 改properties
# shardingjdbc 分片策略
# 配置数据源,给数据源起名称
spring.shardingsphere.datasource.names=m1,m2
# 允许覆盖重名bean
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.jdbc.Driver
spring.shardingsphere.datasource.m1.url=jdbc:mysql://localhost:3306/edu_db_1?useUnicode=true&characterEncoding=utf-8&useSSL=false
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.jdbc.Driver
spring.shardingsphere.datasource.m2.url=jdbc:mysql://localhost:3306/edu_db_2?useUnicode=true&characterEncoding=utf-8&useSSL=false
spring.shardingsphere.datasource.m2.username=root
spring.shardingsphere.datasource.m2.password=root

#指定数据库分布情况,数据库里面表分布情况# m1 m2 course_1 course_2
spring.shardingsphere.sharding.tables.course.actual-data-nodes=m$->{1..2}.course_$->{1..2}
# 指定 course 表里面主键 cid 生成策略 SNOWFLAKE
spring.shardingsphere.sharding.tables.course.key-generator.column=cid
spring.shardingsphere.sharding.tables.course.key-generator.type=SNOWFLAKE

# 指定表分片策略 约定 cid 值偶数添加到 course_1 表,如果 cid 是奇数添加到course_2 表
# +1的原因:如果下标从0开始就不用加,现在下标是从1开始,所以得加。本来下标0代表偶数,+1后下标1代表偶数
spring.shardingsphere.sharding.tables.course.table-strategy.inline.sharding_column=cid
spring.shardingsphere.sharding.tables.course.table-strategy.inline.algorithm_expression=course_$->{cid % 2 + 1}

# 指定数据库分片策略 约定 user_id 是偶数添加 m1,是奇数添加 m2
spring.shardingsphere.sharding.tables.course.database-strategy.inline.sharding_column=user_id
spring.shardingsphere.sharding.tables.course.database-strategy.inline.algorithm_expression=m$->{user_id % 2 + 1}
# 打开 sql 输出日志
spring.shardingsphere.props.sql.show=true
2.4.2 建库表和测试

在这里插入图片描述

@Test
    public void addCourseDb() {
        Course course = new Course();
        course.setCname("javademo1");
        //分库根据 user_id
        course.setUserId(111L);
        course.setCstatus("Normal1");
        courseMapper.insert(course);
    }

    //查询操作
    @Test
    public void findCourseDb() {
        QueryWrapper<Course> wrapper = new QueryWrapper<>();
        //设置 userid 值
        wrapper.eq("user_id", 111L);
        //设置 cid 值
        wrapper.eq("cid", 763127952517890049L);
        Course course = courseMapper.selectOne(wrapper);
        System.out.println(course);
    }

cid与user_id都是奇数,2库的2表
在这里插入图片描述

2.5 Sharding-JDBC 实现垂直分库
2.5.1 改properties
# shardingjdbc 分片策略
# 配置数据源,给数据源起名称
spring.shardingsphere.datasource.names=m1,m2,m0
# 允许覆盖重名bean
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.jdbc.Driver
spring.shardingsphere.datasource.m1.url=jdbc:mysql://localhost:3306/edu_db_1?useUnicode=true&characterEncoding=utf-8&useSSL=false
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.jdbc.Driver
spring.shardingsphere.datasource.m2.url=jdbc:mysql://localhost:3306/edu_db_2?useUnicode=true&characterEncoding=utf-8&useSSL=false
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.jdbc.Driver
spring.shardingsphere.datasource.m0.url=jdbc:mysql://localhost:3306/user_db?useUnicode=true&characterEncoding=utf-8&useSSL=false
spring.shardingsphere.datasource.m0.username=root
spring.shardingsphere.datasource.m0.password=root

# 配置 user_db 数据库里面 t_user 专库专表
spring.shardingsphere.sharding.tables.t_user.actual-data-nodes=m$->{0}.t_user
# 指定 course 表里面主键 cid 生成策略 SNOWFLAKE
spring.shardingsphere.sharding.tables.t_user.key-generator.column=user_id
spring.shardingsphere.sharding.tables.t_user.key-generator.type=SNOWFLAKE

spring.shardingsphere.sharding.tables.t_user.table-strategy.inline.sharding_column=user_id
spring.shardingsphere.sharding.tables.t_user.table-strategy.inline.algorithm_expression=t_user
# 打开 sql 输出日志
spring.shardingsphere.props.sql.show=true
2.5.2 测试
    @Test
    public void addUserDb() {
        User user = new User();
        user.setUsername("lucy");
        user.setUstatus("a");
        userMapper.insert(user);
    }

在这里插入图片描述
其实,我觉着垂直分库和分表不用刻意指定。因为垂直分库是把表分不到不同的库,垂直分表是把一个表拆分成多个表。这在设计之初是可以预见的。

2.6 Sharding-JDBC 操作公共表
2.6.1 建表和实体

分别在user_db、edu_db_2、edu_db_1中执行。

CREATE TABLE `t_udict` (
  `dict_id` BIGINT(20) NOT NULL,
  `uvalue` VARCHAR(64) DEFAULT NULL,
  `ustatus` VARCHAR(32) DEFAULT NULL,
  PRIMARY KEY (`dict_id`)
) ENGINE=INNODB DEFAULT CHARSET=utf8
@Data
@TableName("t_udict")
public class Udict {
    private Long dictid;
    private String ustatus;
    private String uvalue;
}
@Mapper
public interface UdictMapper extends BaseMapper<Udict> {
}
2.6.2 改properties
spring.shardingsphere.sharding.broadcast-tables=t_udict
spring.shardingsphere.sharding.tables.t_udict.key-generator.column=dict_id
spring.shardingsphere.sharding.tables.t_udict.key-generator.type=SNOWFLAKE
2.6.3 测试
@Test
    public void addDict() {
        Udict udict = new Udict();
        udict.setUstatus("a");
        udict.setUvalue("已启用");
        udictMapper.insert(udict);
    }

    //删除操作
    @Test
    public void deleteDict() {
        QueryWrapper<Udict> wrapper = new QueryWrapper<>();
        //设置 userid 值
        wrapper.eq("dict_id", 763535578640678913L);
        udictMapper.delete(wrapper);
    }

在这里插入图片描述

2.7 Sharding-JDBC 实现读写分离
2.7.1 搭建MySQL一主一从
2.7.2Sharding-JDBC配置读写分离策略

读写分离:让主库处理事务性的增删改操作,让从库处理查询操作。

新增配置

# user_db 从服务器
spring.shardingsphere.datasource.s0.type=com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.s0.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.s0.url=jdbc:mysql://localhost:3317/user_db?useUnicode=true&characterEncoding=utf-8&useSSL=false
spring.shardingsphere.datasource.s0.username=root
spring.shardingsphere.datasource.s0.password=root

# 主库从库逻辑数据源定义 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
# 配置 user_db 数据库里面 t_user 专库专表
#spring.shardingsphere.sharding.tables.t_user.actual-data-nodes=m$->{0}.t_user
# t_user 分表策略,固定分配至 ds0 的 t_user 真实表
spring.shardingsphere.sharding.tables.t_user.actual-data-nodes=ds0.t_user

完整配置

# shardingjdbc 分片策略
# 配置数据源,给数据源起名称
spring.shardingsphere.datasource.names=m1,m2,m0,s0
# 允许覆盖重名bean
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.jdbc.Driver
spring.shardingsphere.datasource.m1.url=jdbc:mysql://localhost:3306/edu_db_1?useUnicode=true&characterEncoding=utf-8&useSSL=false
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.jdbc.Driver
spring.shardingsphere.datasource.m2.url=jdbc:mysql://localhost:3306/edu_db_2?useUnicode=true&characterEncoding=utf-8&useSSL=false
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.jdbc.Driver
spring.shardingsphere.datasource.m0.url=jdbc:mysql://localhost:3307/user_db?useUnicode=true&characterEncoding=utf-8&useSSL=false
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.jdbc.Driver
spring.shardingsphere.datasource.s0.url=jdbc:mysql://localhost:3317/user_db?useUnicode=true&characterEncoding=utf-8&useSSL=false
spring.shardingsphere.datasource.s0.username=root
spring.shardingsphere.datasource.s0.password=root

# 主库从库逻辑数据源定义 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
# 配置 user_db 数据库里面 t_user 专库专表
#spring.shardingsphere.sharding.tables.t_user.actual-data-nodes=m$->{0}.t_user
# t_user 分表策略,固定分配至 ds0 的 t_user 真实表
spring.shardingsphere.sharding.tables.t_user.actual-data-nodes=ds0.t_user

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

# 配置 user_db 数据库里面 t_user 专库专表
#spring.shardingsphere.sharding.tables.t_user.actual-data-nodes=m$->{0}.t_user
# 指定 course 表里面主键 cid 生成策略 SNOWFLAKE
spring.shardingsphere.sharding.tables.t_user.key-generator.column=user_id
spring.shardingsphere.sharding.tables.t_user.key-generator.type=SNOWFLAKE

spring.shardingsphere.sharding.tables.t_user.table-strategy.inline.sharding_column=user_id
spring.shardingsphere.sharding.tables.t_user.table-strategy.inline.algorithm_expression=t_user
# 打开 sql 输出日志
spring.shardingsphere.props.sql.show=true
2.7.3 测试
//添加操作
    @Test
    public void addUserDb2MS() {
        User user = new User();
        user.setUsername("jackrose");
        user.setUstatus("b");
        userMapper.insert(user);
    }
    //查询操作
    @Test
    public void findUserDb() {
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        //设置 userid 值
        wrapper.eq("user_id",765512157289775105L);
        User user = userMapper.selectOne(wrapper);
        System.out.println(user);
    }

在这里插入图片描述在这里插入图片描述插入操作在主库,查询操作在从库,读写分离配置成功。

3.Sharding-Proxy

3.1 简介

定位为透明化的数据库代理端,提供封装了数据库二进制协议的服务端版本,用于完成对异构语言的支持。 目前先提供MySQL/PostgreSQL版本,它可以使用任何兼容MySQL/PostgreSQL协议的访问客户端(如:MySQL Command Client, MySQL Workbench, Navicat等)操作数据,对DBA更加友好。

**向应用程序完全透明,可直接当做MySQL/PostgreSQL使用。**
适用于任何兼容MySQL/PostgreSQL协议的的客户端。

在这里插入图片描述

3.2 安装下载

官网下载:https://shardingsphere.apache.org/document/legacy/4.x/document/cn/downloads/
在这里插入图片描述将安装包上传至linux服务器

cd /usr/share
mkdir sharding-proxy
cp apache-shardingsphere-incubating-4.0.1-sharding-proxy-bin.tar.gz sharding-proxy
tar -xvf apache-shardingsphere-incubating-4.0.1-sharding-proxy-bin.tar.gz

3.3 修改配置
3.3.1 权限验证

编辑%SHARDING_PROXY_HOME%\conf\server.yaml。详情请参见配置手册。

Sharding-Proxy使用conf/server.yaml配置注册中心、认证信息以及公用属性。

权限验证:
用于执行登录Sharding Proxy的权限验证。配置用户名、密码、可访问的数据库后,必须使用正确的用户名、密码才可登录Proxy。

authentication:
  users:
    root: # 自定义用户名
      password: root # 自定义用户名
    sharding: # 自定义用户名
      password: sharding # 自定义用户名
      authorizedSchemas: sharding_db, masterslave_db # 该用户授权可访问的数据库,多个用逗号分隔。缺省将拥有root权限,可访问全部数据库。

认证信息配置:
conf/server.yaml
放开对应的注释
在这里插入图片描述

3.3.2 分库分表配置

conf/config-sharding.yaml
将MySQL的注释放开,其他的不动。schemaName不能重复。

######################################################################################################
#
# If you want to connect to MySQL, you should manually copy MySQL driver to lib directory.
#
######################################################################################################

schemaName: sharding_db

dataSources:
  ds_0:
    url: jdbc:mysql://localhost:3307/demo_ds_0?serverTimezone=UTC&useSSL=false
    username: root
    password: root
    connectionTimeoutMilliseconds: 30000
    idleTimeoutMilliseconds: 60000
    maxLifetimeMilliseconds: 1800000
    maxPoolSize: 50
  ds_1:
    url: jdbc:mysql://localhost:3307/demo_ds_1?serverTimezone=UTC&useSSL=false
    username: root
    password: root
    connectionTimeoutMilliseconds: 30000
    idleTimeoutMilliseconds: 60000
    maxLifetimeMilliseconds: 1800000
    maxPoolSize: 50
#
shardingRule:
  tables:
    t_order:
      actualDataNodes: ds_${0..1}.t_order_${0..1}
      tableStrategy:
        inline:
          shardingColumn: order_id
          algorithmExpression: t_order_${order_id % 2}
      keyGenerator:
        type: SNOWFLAKE
        column: order_id
    t_order_item:
      actualDataNodes: ds_${0..1}.t_order_item_${0..1}
      tableStrategy:
        inline:
          shardingColumn: order_id
          algorithmExpression: t_order_item_${order_id % 2}
      keyGenerator:
        type: SNOWFLAKE
        column: order_item_id
  bindingTables:
    - t_order,t_order_item
  defaultDatabaseStrategy:
    inline:
      shardingColumn: user_id
      algorithmExpression: ds_${user_id % 2}
  defaultTableStrategy:
    none:

If you want to connect to MySQL, you should manually copy MySQL driver to lib directory

根据注释提示,需要下载MySQL 的驱动包。

官网下载太慢,来此处下载。https://downloads.mysql.com/archives/c-j/
在这里插入图片描述在这里插入图片描述
在这里插入图片描述下载完成上传至linux服务器并解压。解压后将jar包放置到sharding-proxy解压目录的lib目录下
在这里插入图片描述

3.3.3 读写分离配置

此时搭建的是一主一从,但是每个数据库实例里面有两个库

第一个数据库的读写分离配置:

conf/config-master_slave.yaml

######################################################################################################
#
# If you want to connect to MySQL, you should manually copy MySQL driver to lib directory.
#
######################################################################################################

########################
#
# 第一个数据库的读写分离
# 读从库,写更新删除在主库
# 
########################

schemaName: sharding_db_0
#
dataSources:
  master_0_ds:
    url: jdbc:mysql://192.168.10.10:3307/demo_ds_0?serverTimezone=UTC&useSSL=false
    username: root
    password: root
    connectionTimeoutMilliseconds: 30000
    idleTimeoutMilliseconds: 60000
    maxLifetimeMilliseconds: 1800000
    maxPoolSize: 50
  slave_ds_0:
    url: jdbc:mysql://192.168.10.10:3317/demo_ds_0?serverTimezone=UTC&useSSL=false
    username: root
    password: root
    connectionTimeoutMilliseconds: 30000
    idleTimeoutMilliseconds: 60000
    maxLifetimeMilliseconds: 1800000
    maxPoolSize: 50

masterSlaveRule:
  name: ms_ds
  masterDataSourceName: master_0_ds
  slaveDataSourceNames:
    - slave_ds_0
#    - slave_ds_1
  loadBalanceAlgorithmType: ROUND_ROBIN

第二个数据库的读写分离配置:

conf/config-master_slave_2.yaml

全部配置完之后,然后启动服务:

######################################################################################################
#
# If you want to connect to MySQL, you should manually copy MySQL driver to lib directory.
#
######################################################################################################

########################
#
# 第2个数据库的读写分离
# 读从库,写更新删除在主库
# 
########################

schemaName: sharding_db_1
#
dataSources:
  master_1_ds:
    url: jdbc:mysql://192.168.10.10:3307/demo_ds_1?serverTimezone=UTC&useSSL=false
    username: root
    password: root
    connectionTimeoutMilliseconds: 30000
    idleTimeoutMilliseconds: 60000
    maxLifetimeMilliseconds: 1800000
    maxPoolSize: 50
  slave_ds_1:
    url: jdbc:mysql://192.168.10.10:3317/demo_ds_1?serverTimezone=UTC&useSSL=false
    username: root
    password: root
    connectionTimeoutMilliseconds: 30000
    idleTimeoutMilliseconds: 60000
    maxLifetimeMilliseconds: 1800000
    maxPoolSize: 50

masterSlaveRule:
  name: ms_ds_1
  masterDataSourceName: master_1_ds
  slaveDataSourceNames:
    - slave_ds_1
#    - slave_ds_1
  loadBalanceAlgorithmType: ROUND_ROBIN
3.3.4 更新主从库的配置

docker stop mysql-master mysql-slave01

cd /mydata/mysql/master/conf
vim my.cnf
# 增加如下配置
binlog-do-db=demo_ds_0
binlog-do-db=demo_ds_1
cd /mydata/mysql/slave/conf
vim my.cnf
# 增加如下配置
replicate_wild_do_table=demo_ds_0.%
replicate_wild_do_table=demo_ds_1.% 

docker start mysql-master mysql-slave01

3.3.5 启动

连接到主库,创建 demo_ds_0 demo_ds_1 两个数据库,然后切换到从库,发现数据库已同步正常
在这里插入图片描述启动需要依赖jdk,所以若未安装jdk,可参考 Linux环境安装jdk

进入到sharding-proxy 的解压目录的bin目录下,执行 sh start.sh 3388 指定在3388端口上启动

进入logs目录下查看stdout.log,末尾出现ACTIVE 说明启动成功。

进入云服务器开启3388端口

使用SQLyog DBeaver 命令行连接均出现异常,改用navicat连接正常。在简介中有说明。

在这里插入图片描述

3.3.6 验证

创建表结构:

CREATE TABLE t_order (
order_id bigint(20)NOT NULL AUTO_INCREMENT,
user_id int(11)NOT NULL,
status varchar(50) DEFAULT NULL,
PRIMARY KEY (order_id)
)ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;

CREATE TABLE t_order_item(
order_item_id bigint (20)NOT NULL,
order_id bigint (20)NOT NULL,
user_id int (11)NOT NULL,
content varchar (255) DEFAULT NULL,
status varchar(50) DEFAULT NULL,
PRIMARY KEY(order_item_id)
)ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;

插入数据

insert into t_order (user_id,status) VALUES(1,1)
insert into t_order (user_id,status) VALUES(3,2)
insert into t_order (user_id,status) VALUES(2,3)
insert into t_order (user_id,status) VALUES(4,4)

发现分库分表正常,主从同步正常。

4. Springboot集成sharding-proxy

4.1 注释掉sharding-jdbc-demo中多余的代码

注释pom多余依赖
在这里插入图片描述注释测试类中其余的mapper及代码
注释多余的实体类和多余的mapper
在这里插入图片描述

4.2 新建application.yml
server:
  port: 8001

spring:
  application:
    name: sharding-jdbc-demo
  datasource:
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://localhost:3388/sharding_db?useUnicode=true&characterEncoding=utf-8&useSSL=false
    username: root
    password: root

此处直接连接sharding-proxy,把sharding-proxy当成一个数据库来管理。连接sharding_db库。

4.3 建实体类和mapper
@Data
@TableName("t_order")
@ToString
public class Order {
    @TableId("order_id")
    private Long orderId;
    private Long userId;
    private String status;
}

实体类中需要制定主键id,否则会报错

@Mapper
public interface OrderMapper extends BaseMapper<Order> {
}
4.4 测试

    @Resource
    private OrderMapper orderMapper;
    
    @Test
    public void addOrder() {
        Order order = new Order();
        order.setUserId(6L);
        order.setStatus("5");
        orderMapper.insert(order);
        log.info("插入成功!"+order);
    }
    @Test
    public void findOrder() {
        QueryWrapper<Order> wrapper = new QueryWrapper<>();
        //设置 userid 值
        wrapper.eq("user_id",5L);
        Order order = orderMapper.selectOne(wrapper);
        log.info("查询成功!"+order);
    }

在这里插入图片描述插入和查询成功,大功告成!!!

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值