shardingsphere-jdbc(1):实现数据库主从同步、读写分离


前言

Apache ShardingSphere 是一款分布式的数据库生态系统, 可以将任意数据库转换为分布式数据库,并通过数据分片、弹性伸缩、加密等能力对原有数据库进行增强(引自官网)。


一、配置测试环境

1.安装docker

该操作不做过多赘述,博主有一篇博客是专门用于介绍如何部署docker环境的,链接放下面
docker安装教程

2.安装mysql(基于docker)

2.1 拉取mysql镜像

博主下载的是8.0.28版本的mysql,如果需要更换版本只需要修改后面的版本号就可以

 docker pull mysql:8.0.28

2.2 启动mysql

2.2.1 简单启动

该启动操作,不会在服务器本地记录mysql日志、也无法实现数据本地持久化,但是也算是启动成功了

 docker run -p 本地映射端口:3306 -e MYSQL_ROOT_PASSWORD=密码 -d mysql:8.0.28
2.2.2 基于配置启动

想实现本地数据持久化可以使用下面的启动方式

拷贝一份mysql配置文件到服务器本地,配置根据个人需求自行修改

docker cp e407810d1149:/etc/mysql/my.cnf /software/mysql-master

e407810d1149 启动的mysql容器ID
/software/mysql-master 服务器本地配置文件存储路径

启动mysql容器

docker run -d \
-p 本地映射端口:3306 \
--privileged=true \
-v mysql日志本地存储路径:/var/log/mysql \
-v mysql数据持久化路径:/var/lib/mysql \
-v mysql配置文件本地存储路径:/etc/mysql/conf.d \
--name 自定义该启动容器名称 \
-e MYSQL_ROOT_PASSWORD=root账号连接数据库密码 \
mysql:8.0.28

本地映射端口号最好不要使用3306这种常用端口,因为博主的云服务器因为开放了该端口被攻击过

2.3 搭建mysql主从服务

因为只有一台服务器的缘故,所以主从服务都在一台服务器上搭建了(如果条件允许也可以在多个服务器上搭建环境)

因为使用了docker的缘故这一步就变得非常简单了,将上序步骤2.2.2执行多次就可以搭建多个mysql服务了,需要改动的就是 本地映射端口 和 自定义的容器名称,类似于下图:
在这里插入图片描述

2.3.1 注意事项

每个mysql服务都是有一个单独的配置、数据、日志存储路径的,这一点在启动mysql服务时也要修改

在这里插入图片描述

每个mysql服务的 server-id 这一项配置是不相同的,不然启动主从配置时会不生效,该配置项在my.cnf中配置

在这里插入图片描述

二、配置mysql多服务的主从同步

1.主服务器操作

1.1 创建一个用户给从服务做数据拷贝操作

#创建 slave 用户
create user 'slave'@'%';

#为slave用户 设置密码
alter user 'slave'@'%' IDENTIFIED WITH mysql_native_password by '自定义密码';

# 赋予复制权限
GRANT replication SLAVE ON *.* TO 'slave'@'%';

# 刷新权限
FLUSH PRIVILEGES;

1.2获取binlog信息

# 用于获取MySQL主服务器(Master)的二进制日志(Binlog)复制状态信息
show master status;

在这里插入图片描述

2.从服务器操作

2.1 进行主从复制配置

change master to 
master_host = '服务器IP',
master_user = 'slave',
master_password = '自定义slave密码',
master_port = 主服务端口,
master_log_file = 'Binlog File字段信息',
master_log_pos = Binlog Position字段信息;

2.2 启动从服务器复制功能

start slave;

2.3 查看启动状态

show slave status;

在这里插入图片描述

此处重点关注 Slave_IO_Running、Slave_SQL_Running这两个参数,两者都为YES表示启动成功,两者任意一个部位YES都是启动失败

如何查看启动失败的原因也很简单,如果启动失败该结果的以下四个字段会记录错误信息,将其复制到网上一查就清楚了
在这里插入图片描述

2.4主从复制功能重启、停止

#停止主从复制
stop slave;

#重启主从复制
reset master;

2.5查看服务serverID

show variables like 'server_id';

如果有多个从服务需要开启主从操作,将上面的命令在另外的从服务器中执行就行

3.测试配置结果

在master服务中进行创建数据库、表、插入数据、删除数据操作 查看slave服务是否也是进行了相同的操作,如果都是同步执行,那就是已经成功开启了主从同步了

三、使用 shardingsphere-jdbc 操作数据库进行读写分离

1.引入pom依赖

创建一个springboot应用程序,引入以下依赖

博主测试使用的shardingsphere-jdbc-core-spring-boot-starter版本为5.1.2,看了下官方文档,5.1.2以后的配置可能会跟此版本有区别,最好版本同步

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

        <!--shardingsphere-jdbc 主要依赖-->
        <dependency>
            <groupId>org.apache.shardingsphere</groupId>
            <artifactId>shardingsphere-jdbc-core-spring-boot-starter</artifactId>
            <version>5.1.2</version>
        </dependency>

<!--        mysql驱动-->
        <dependency>
            <groupId>com.mysql</groupId>
            <artifactId>mysql-connector-j</artifactId>
            <scope>runtime</scope>
        </dependency>

        <!--mybatis-plus -->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.5.3.1</version>
        </dependency>

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

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

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
    </dependencies>

2.配置shardingsphere-jdbc

以下配置项详情可以参考官网
shardingsphere-jdbc5.1.2官方文档

spring:
  application:
    name: sharding-jdbc-demo
  shardingsphere:
#    内存模式(在5.1.2之后的版本貌似没有这个模式)
    mode:
      type: Memory
#    多数据源配置
    datasource:
#      名字随便定义
      names: master,slave1,slave2
      master:
        type: com.zaxxer.hikari.HikariDataSource
        driver-class-name : com.mysql.cj.jdbc.Driver
        jdbc-url: jdbc:mysql://服务器IP:服务端口/库名称?characterEncoding=utf8&useSSL=true&serverTimezone=GMT%2B8
        username: root
        password: 自定义密码
      slave1:
        type: com.zaxxer.hikari.HikariDataSource
        driver-class-name: com.mysql.cj.jdbc.Driver
        jdbc-url: jdbc:mysql://服务器IP:服务端口/库名称?characterEncoding=utf8&useSSL=true&serverTimezone=GMT%2B8
        username: root
        password: 自定义密码
      slave2:
        type: com.zaxxer.hikari.HikariDataSource
        driver-class-name: com.mysql.cj.jdbc.Driver
        jdbc-url: jdbc:mysql://服务器IP:服务端口/库名称?characterEncoding=utf8&useSSL=true&serverTimezone=GMT%2B8
        username: root
        password: 自定义密码
#        配置 读写分离
    rules:
      readwrite-splitting:
        data-sources:
#          myds 这个名字是可以自定义的  master,slave1,slave2 三个数据源共同构成了 myds 这个逻辑数据源
          myds:
#            类型为 Static,Dynamic
            type: Static
            props:
#              写 数据源
              write-data-source-name: master
#              读 数据源 多个用逗号隔开
              read-data-source-names: slave1,slave2
#              负载均衡算法名称(自定义)
              load-balancer-name: alg_weight

#        负载均衡算法类型
        load-balancers:
#          轮询算法
          alg_round:
            type: ROUND_ROBIN
#          随机访问算法
          alg_random:
            type: RANDOM
#          权重访问算法(使用中的读库都必须配置权重)
          alg_weight:
            type: WEIGHT
            props:
              slave1: 1
              slave2: 2
    props:
#      打印sql
      sql-show: true

配置完后 执行主程序 启动试试,如果正常启动就表示配置正确,如果启动失败肯定是哪个参数配置错误了,最好的解决办法就是参考官方文档,里面说明都很详细

3.测试是否实现读写分离

第二步的yml文件 配置了 master 服务为写操作 slave1,slave2 为读操作,我们来测试是否实现读写分离

1.创建实体类

@Data
@TableName("t_user")
public class User {

    @TableId(type= IdType.AUTO)
    private Long id;

    private String username;
}

2.创建mapper层

@Mapper
public interface UserMapper extends BaseMapper<User> {
}

3.开始测试

创建测试方法执行 新增、查询 操作

@SpringBootTest
public class ReadWriteTest {

    @Autowired
    private UserMapper userMapper;

    /**
     * 写数据测试
     */
    @Test
    public void test1(){
        User user = new User();
        user.setUsername("晨曦");
        userMapper.insert(user);
    }

    @Test
    public void test2(){
        List<User> users = userMapper.selectList(null);
    }

    @Transactional
    @Test
    public void test3(){
        User user = new User();
        user.setUsername("李四");
        userMapper.insert(user);

        List<User> users = userMapper.selectList(null);
    }
}

test1执行的打印结果:
在这里插入图片描述

该结果表示实际执行 sql 该添加数据的操作在master服务中执行了,此时在开启主从同步后,其实slave服务也复制了该数据,可以在数据库中进行查看

test2执行的打印结果:
在这里插入图片描述

该结果表示实际执行 sql 表示查询的操作是在slave1 从服务进行查询的,这两个示例表示已经是实现了 读写分离操作的

test3执行的打印结果:
在这里插入图片描述

test3展示的是在执行事务操作时的情况,在分库的情况下执行事务操作,是不会进行多个库操作的,其操作都是在master数据库进行的

总结

本篇文章主要介绍了分库情况下多服务的主从服务如何进行配置,springboot程序中shardingSphere-jdbc是如何进行的读写分离操作,希望对各位小伙伴有帮助。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值