ShardingSphere主从复制

数据库主从复制配置:

mysql主从复制从0到1
docker启动多个mysql服务

安装指定版本mysql

sudo docker pull mysql:8.0.29

主服务master-3307

启动主服务3307

docker run -d \
-p 3307:3306 \
-v /study/shardingsphere/mysql/master/conf:/etc/mysql/conf.d \
-v /study/shardingsphere/mysql/master/data:/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD=123456 \
--name dk-mysql-master \
mysql:8.0.29

创建MySQL主服务器配置文件:
默认情况下MySQL的binlog日志是自动开启的,可以通过如下配置定义一些可选配置

vim /study/shardingsphere/mysql/master/conf/my.cnf

配置如下内容

[mysqld]
# 服务器唯一id,默认值1
server-id=1
# 设置日志格式,默认值ROW
binlog_format=STATEMENT
# 二进制日志名,默认binlog
# log-bin=binlog
# 设置需要复制的数据库,默认复制全部数据库
#binlog-do-db=mytestdb
# 设置不需要复制的数据库
#binlog-ignore-db=mysql
#binlog-ignore-db=infomation_schema

binlog格式说明:

  • binlog_format=STATEMENT:日志记录的是主机数据库的写指令,性能高,但是now()之类的函数以及获取系统参数的操作会出现主从数据不同步的问题。
  • binlog_format=ROW(默认):日志记录的是主机数据库的写后的数据,批量操作时性能较差,解决now()或者 user()或者 @@hostname 等操作在主从机器上不一致的问题。
  • binlog_format=MIXED:是以上两种level的混合使用,有函数用ROW,没函数用STATEMENT,但是无法识别系统变量

重启MySQL容器

docker restart dk-mysql-master

设置mysql容器在docker启动的时候启动

docker update dk-mysql-master --restart=always

使用命令行登录MySQL主服务器:

#进入容器:env LANG=C.UTF-8 避免容器中显示中文乱码
docker exec -it dk-mysql-master env LANG=C.UTF-8 /bin/bash
#进入容器内的mysql命令行
mysql -uroot -p
#修改默认密码校验方式(不执行,navicat无法连接
ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY '123456';
  • 主机中创建slave用户:
-- 创建slave用户
CREATE USER 'dk_slave'@'%';
-- 设置密码
ALTER USER 'dk_slave'@'%' IDENTIFIED WITH mysql_native_password BY '123456';
-- 授予复制权限
GRANT REPLICATION SLAVE ON *.* TO 'dk_slave'@'%';
-- 刷新权限
FLUSH PRIVILEGES;
  • 主机中查询master状态:

执行完此步骤后不要再操作主服务器MYSQL,防止主服务器状态值变化
SHOW MASTER STATUS;
记下File和Position的值。执行完此步骤后不要再操作主服务器MYSQL,防止主服务器状态值变化。

ShardingSphere主从复制_第1张图片

从服务slave1-3308

启动从服务slave1-3308

docker run -d \
-p 3308:3306 \
-v /study/shardingsphere/mysql/slave1/conf:/etc/mysql/conf.d \
-v /study/shardingsphere/mysql/slave1/data:/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD=123456 \
--name dk-mysql-slave1 \
mysql:8.0.29

创建MySQL主服务器配置文件:
默认情况下MySQL的binlog日志是自动开启的,可以通过如下配置定义一些可选配置

vim /study/shardingsphere/mysql/slave1/conf/my.cnf

配置如下内容:

[mysqld]
# 服务器唯一id,每台服务器的id必须不同,如果配置其他从机,注意修改id
server-id=2
# 中继日志名,默认xxxxxxxxxxxx-relay-bin
#relay-log=relay-bin

重启MySQL容器

docker restart dk-mysql-slave1

设置mysql容器在docker启动的时候启动

docker update dk-mysql-slave1 --restart=always

  • step3:使用命令行登录MySQL从服务器:
#进入容器:
docker exec -it dk-mysql-slave1 env LANG=C.UTF-8 /bin/bash
#进入容器内的mysql命令行
mysql -uroot -p
#修改默认密码校验方式
ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY '123456';
  • step4:在从机上配置主从关系:

从机上执行以下SQL操作

CHANGE MASTER TO MASTER_HOST='192.168.229.128', 
MASTER_USER='dk_slave',MASTER_PASSWORD='123456', MASTER_PORT=3307,
MASTER_LOG_FILE='binlog.000003',MASTER_LOG_POS=1342;

SHOW MASTER STATUS;

STOP SLAVE;
CHANGE MASTER TO MASTER_HOST='192.168.229.128', 
MASTER_USER='dk_slave',MASTER_PASSWORD='123456', MASTER_PORT=3307,
MASTER_LOG_FILE='binlog.000003',MASTER_LOG_POS=1342;

START SLAVE;

-- 查看同步状态(不需要分号)
SHOW SLAVE STATUS\G

ShardingSphere主从复制_第2张图片

从服务slave2-3309

启动从服务slave2-3309

docker run -d \
-p 3309:3306 \
-v /study/shardingsphere/mysql/slave2/conf:/etc/mysql/conf.d \
-v /study/shardingsphere/mysql/slave2/data:/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD=123456 \
--name dk-mysql-slave2 \
mysql:8.0.29

创建MySQL主服务器配置文件:
默认情况下MySQL的binlog日志是自动开启的,可以通过如下配置定义一些可选配置

vim /study/shardingsphere/mysql/slave2/conf/my.cnf

配置如下内容:

[mysqld]
# 服务器唯一id,每台服务器的id必须不同,如果配置其他从机,注意修改id
server-id=3
# 中继日志名,默认xxxxxxxxxxxx-relay-bin
#relay-log=relay-bin

重启MySQL容器

docker restart dk-mysql-slave2

设置mysql容器在docker启动的时候启动

docker update dk-mysql-slave2 --restart=always

  • step3:使用命令行登录MySQL从服务器:
#进入容器:
docker exec -it dk-mysql-slave2 env LANG=C.UTF-8 /bin/bash
#进入容器内的mysql命令行
mysql -uroot -p
#修改默认密码校验方式
ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY '123456';
  • step4:在从机上配置主从关系:

从机上执行以下SQL操作

CHANGE MASTER TO MASTER_HOST='192.168.229.128', 
MASTER_USER='dk_slave',MASTER_PASSWORD='123456', MASTER_PORT=3307,
MASTER_LOG_FILE='binlog.000003',MASTER_LOG_POS=1342;

SHOW MASTER STATUS;

STOP SLAVE;
CHANGE MASTER TO MASTER_HOST='192.168.229.128', 
MASTER_USER='dk_slave',MASTER_PASSWORD='123456', MASTER_PORT=3307,
MASTER_LOG_FILE='binlog.000003',MASTER_LOG_POS=1342;
START SLAVE;


-- 查看同步状态(不需要分号)
SHOW SLAVE STATUS\G

启动从机的复制功能,执行SQL:

START SLAVE;
-- 查看状态(不需要分号)
SHOW SLAVE STATUS\G

状态正常后创建测试表

CREATE DATABASE db_user;
USE db_user;
CREATE TABLE t_user (
id BIGINT AUTO_INCREMENT,
uname VARCHAR(30),
PRIMARY KEY (id)
);
INSERT INTO t_user(uname) VALUES(‘zhang3’);
INSERT INTO t_user(uname) VALUES(@@hostname);

ShardingSphere接入主从数据库

我是idea直接创建的空白springboot项目,替换pom为下面内容

pom.xml


<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.0modelVersion>
  <groupId>com.dkgroupId>
  <artifactId>ShardingJdbcDemoartifactId>
  <version>0.0.1-SNAPSHOTversion>
  <name>ShardingJdbcDemoname>
  <description>Demo project for Spring Bootdescription>
  <properties>
    <java.version>1.8java.version>
    <project.build.sourceEncoding>UTF-8project.build.sourceEncoding>
    <project.reporting.outputEncoding>UTF-8project.reporting.outputEncoding>
    <spring-boot.version>2.3.12.RELEASEspring-boot.version>
  properties>

  <dependencies>
    <dependency>
      <groupId>org.springframework.bootgroupId>
      <artifactId>spring-boot-starter-webartifactId>
    dependency>

    <dependency>
      <groupId>org.apache.shardingspheregroupId>
      <artifactId>shardingsphere-jdbc-core-spring-boot-starterartifactId>
      <version>5.1.1version>
    dependency>

    <dependency>
      <groupId>mysqlgroupId>
      <artifactId>mysql-connector-javaartifactId>
      <scope>runtimescope>
    dependency>

    <dependency>
      <groupId>com.baomidougroupId>
      <artifactId>mybatis-plus-boot-starterartifactId>
      <version>3.3.1version>
    dependency>

    <dependency>
      <groupId>org.projectlombokgroupId>
      <artifactId>lombokartifactId>
      <optional>trueoptional>
    dependency>

    <dependency>
      <groupId>org.springframework.bootgroupId>
      <artifactId>spring-boot-starter-testartifactId>
      <scope>testscope>
      <exclusions>
        <exclusion>
          <groupId>org.junit.vintagegroupId>
          <artifactId>junit-vintage-engineartifactId>
        exclusion>
      exclusions>
    dependency>
  dependencies>


  <dependencyManagement>
    <dependencies>
      <dependency>
        <groupId>org.springframework.bootgroupId>
        <artifactId>spring-boot-dependenciesartifactId>
        <version>${spring-boot.version}version>
        <type>pomtype>
        <scope>importscope>
      dependency>
    dependencies>
  dependencyManagement>

  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.pluginsgroupId>
        <artifactId>maven-compiler-pluginartifactId>
        <version>3.8.1version>
        <configuration>
          <source>1.8source>
          <target>1.8target>
          <encoding>UTF-8encoding>
        configuration>
          plugin>
          <plugin>
          <groupId>org.springframework.bootgroupId>
          <artifactId>spring-boot-maven-pluginartifactId>
          <version>${spring-boot.version}version>
          <configuration>
          <mainClass>com.dk.shardingjdbcdemo.ShardingJdbcDemoApplicationmainClass>
          <skip>trueskip>
          configuration>
          <executions>
          <execution>
          <id>repackageid>
          <goals>
          <goal>repackagegoal>
          goals>
          execution>
          executions>
          plugin>
          plugins>
          build>

          project>

配置点主要在application.properties,一个从服务和多个不一样,所以下面分开测试
官网地址
https://shardingsphere.apache.org/document/5.1.1/cn/user-manual/shardingsphere-jdbc/spring-boot-starter/rules/readwrite-splitting/

一主一从

application.properties
spring.application.name=ShardingJdbcDemo
server.servlet.context-path=/shardingJdbcDemo

spring.shardingsphere.props.sql-show=true

#内存模式
spring.shardingsphere.mode.type=Memory

# 配置真实数据源
spring.shardingsphere.datasource.names=master,slave1

# 配置第 1 个数据源
spring.shardingsphere.datasource.master.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.master.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.master.jdbc-url=jdbc:mysql://192.168.229.128:3307/db_user
spring.shardingsphere.datasource.master.username=root
spring.shardingsphere.datasource.master.password=123456

# 配置第 2 个数据源
spring.shardingsphere.datasource.slave1.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.slave1.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.slave1.jdbc-url=jdbc:mysql://192.168.229.128:3308/db_user
spring.shardingsphere.datasource.slave1.username=root
spring.shardingsphere.datasource.slave1.password=123456

# 读写分离类型,如: Static,Dynamic
spring.shardingsphere.rules.readwrite-splitting.data-sources.myds.type=Static
# 自动发现数据源名称(与数据库发现配合使用)
spring.shardingsphere.rules.readwrite-splitting.data-sources.myds.props.auto-aware-data-source-name=
# 写数据源名称
spring.shardingsphere.rules.readwrite-splitting.data-sources.myds.props.write-data-source-name=master
# 读数据源名称,多个从数据源用逗号分隔
spring.shardingsphere.rules.readwrite-splitting.data-sources.myds.props.read-data-source-names=slave1
# 负载均衡算法名称
spring.shardingsphere.rules.readwrite-splitting.data-sources.myds.load-balancer-name=round-balancer

# 负载均衡算法配置
# 负载均衡算法类型
spring.shardingsphere.rules.readwrite-splitting.load-balancers.round-balancer.type=ROUND_ROBIN
# 负载均衡算法属性配置
#spring.shardingsphere.rules.readwrite-splitting.load-balancers.round-balancer.props.xxx=
实体类UserPo
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Builder;
import lombok.Data;

@Data
    @TableName("t_user")
    @Builder
    public class UserPo {
        /**
* id BIGINT AUTO_INCREMENT,
* uname VARCHAR(30),
* PRIMARY KEY (id)
*/
        @TableId(type = IdType.AUTO)
        private Long id;
        private String uname;
    }
UserMapper
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.dk.shardingjdbcdemo.dto.UserPo;
import org.apache.ibatis.annotations.Mapper;

@Mapper
    public interface UserMapper extends BaseMapper<UserPo> {
    }
测试类
import com.dk.shardingjdbcdemo.dto.UserPo;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;

import javax.annotation.Resource;

@SpringBootTest
public class UserMapperTest {
    @Resource
    private  UserMapper userMapper;

    @Test
    public void testInsertUser(){
        userMapper.insert(UserPo.builder().uname("李四").build());
        userMapper.insert(UserPo.builder().uname("李四2").build());
        userMapper.insert(UserPo.builder().uname("李四3").build());
        userMapper.insert(UserPo.builder().uname("李四4").build());

        userMapper.selectList(null);
        userMapper.selectList(null);
        userMapper.selectList(null);
        userMapper.selectList(null);
    }
}

测试结果
ShardingSphere主从复制_第3张图片
从结果可以看出,已经实现了主服务插入,从服务查询

一主两从

application.properties
spring.application.name=ShardingJdbcDemo
server.servlet.context-path=/shardingJdbcDemo

spring.shardingsphere.props.sql-show=true

#内存模式
spring.shardingsphere.mode.type=Memory

# 配置真实数据源
spring.shardingsphere.datasource.names=master,slave1,slave2

# 配置第 1 个数据源
spring.shardingsphere.datasource.master.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.master.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.master.jdbc-url=jdbc:mysql://192.168.229.128:3307/db_user
spring.shardingsphere.datasource.master.username=root
spring.shardingsphere.datasource.master.password=123456

# 配置第 2 个数据源
spring.shardingsphere.datasource.slave1.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.slave1.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.slave1.jdbc-url=jdbc:mysql://192.168.229.128:3308/db_user
spring.shardingsphere.datasource.slave1.username=root
spring.shardingsphere.datasource.slave1.password=123456

# 配置第 2 个数据源
spring.shardingsphere.datasource.slave2.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.slave2.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.slave2.jdbc-url=jdbc:mysql://192.168.229.128:3309/db_user
spring.shardingsphere.datasource.slave2.username=root
spring.shardingsphere.datasource.slave2.password=123456

# 读写分离类型,如: Static,Dynamic
spring.shardingsphere.rules.readwrite-splitting.data-sources.myds.type=Static
# 自动发现数据源名称(与数据库发现配合使用)
spring.shardingsphere.rules.readwrite-splitting.data-sources.myds.props.auto-aware-data-source-name=
# 写数据源名称
spring.shardingsphere.rules.readwrite-splitting.data-sources.myds.props.write-data-source-name=master
# 读数据源名称,多个从数据源用逗号分隔
spring.shardingsphere.rules.readwrite-splitting.data-sources.myds.props.read-data-source-names=slave1,slave2
# 负载均衡算法名称
spring.shardingsphere.rules.readwrite-splitting.data-sources.myds.load-balancer-name=round-balancer

# 负载均衡算法配置
# 负载均衡算法类型
spring.shardingsphere.rules.readwrite-splitting.load-balancers.round-balancer.type=ROUND_ROBIN
# 负载均衡算法属性配置
#spring.shardingsphere.rules.readwrite-splitting.load-balancers.round-balancer.props.xxx=

其他代码同上

测试结果
ShardingSphere主从复制_第4张图片

从图上来看,插入走master服务,查询轮询2台从服务,达到预期

事务

如果有事务的话,都会走master服务,

你可能感兴趣的:(数据库,mysql,服务器)