Sharding JDBC 实现读写分离+分库分表-2主4从

IP
Mysql_Master1172.16.94.5数据库 Master可读写、主库
Mysql_Slave1172.16.94.6数据库 Slave只读、从库
Mysql_Slave2172.16.94.10数据库 Slave只读、从库
Mysql_Master11172.16.94.17数据库 Master11可读写、主库
Mysql_Slave11172.16.94.18数据库 Slave11只读、从库
Mysql_Slave22172.16.94.19数据库 Slave22只读、从库

MySQL 主从搭建 一主二从

主库配置/etc/my.cnf
#bin_log 配置
log_bin=mysql-bin
server-id=1
sync-binlog=1
binlog-ignore-db=information_schema
binlog-ignore-db=performance_schema
binlog-ignore-db=sys
#relay_log 配置
relay_log=mysql-relay-bin
log_slave_updates=1
relay_log_purge=0
两台从库配置/etc/my.cnf
#bin_log 配置
log_bin=mysql-bin
#服务器 ID,从库 2、3
server-id=2
sync-binlog=1
binlog-ignore-db=information_schema
binlog-ignore-db=mysql
binlog-ignore-db=performance_schema
#relay_log 配置
relay_log=mysql-relay-bin
log_slave_updates=1
relay_log_purge=0
read_only=1
三台分别重启服务
systemctl restart mysqld
主库开启权限
#进入mysql
grant replication slave on *.* to 'root'@'%' identified by 'root';
grant all privileges on *.* to 'root'@'%' identified by 'root';
flush privileges;
grant replication slave on *.* to 'mha'@'%' identified by '123123';
grant all privileges on *.* to 'mha'@'%' identified by '123123';
flush privileges;
两台从库建立主从关系
#查看是否以前有配置信息,若有则去除掉
show slave status;
#stop slave;
#reset slave all;
#在主库查看binlog状态
#show master status \G;
#从库设置主库信息
change master to master_host='172.16.94.5',master_port=3306,master_user='root',master_password='root',
master_log_file='mysql-bin.000014',master_log_pos=154;
#开启从库
start slave;
#再次查看从库配置信息
show slave status \G;

分别复制主库和两个从库

虚拟机直接克隆

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-k0d8OUZW-1627401911737)(https://b3logfile.com/siyuan/1619927307428/assets/image-20210727175931-1hcjaou.png)]

修改主库 2 配置/etc/my.cnf

server-id=11

修改从库 11、22 配置/etc/my.cnf

vim /etc/my.cnf
server-id=12
server-id=13

查找下 auto.cnf 文件的位置,全部修改

find / -name "auto.cnf"
vim /var/lib/mysql/auto.cnf
[auto]
server-uuid=356fc1ff-e339-11eb-bbea-000c29c18311

查看主库 22 的状态

mysql> show master status \G;
*************************** 1. row ***************************
             File: mysql-bin.000015
         Position: 154
     Binlog_Do_DB: 
 Binlog_Ignore_DB: information_schema,performance_schema,sys
Executed_Gtid_Set: 
1 row in set (0.00 sec)

修改从库 22 和从库 33 的主库


mysql> stop slave;
Query OK, 0 rows affected (0.01 sec)

mysql> reset slave all;
Query OK, 0 rows affected (0.01 sec)

mysql> change master to master_host='172.16.94.17',master_port=3306,master_user='root',master_password='root',
    -> master_log_file='mysql-bin.000015',master_log_pos=154;
Query OK, 0 rows affected, 2 warnings (0.01 sec)

mysql> start slave;
Query OK, 0 rows affected (0.01 sec)

mysql> show slave status \G;
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 172.16.94.17
                  Master_User: root
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql-bin.000015
          Read_Master_Log_Pos: 154
               Relay_Log_File: mysql-relay2-bin.000002
                Relay_Log_Pos: 320
        Relay_Master_Log_File: mysql-bin.000015
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
1 row in set (0.00 sec)

重启下这三台服务

systemctl restart mysqld

初始化数据

主库分别创建 lane3、lane5 和 c_order 表

➜  ~ mysql -uroot -proot
mysql> create database lane5;
Query OK, 1 row affected (0.00 sec)
mysql> use lane5;
Database changed
mysql> CREATE TABLE `c_order` (
    -> `id` BIGINT ( 20 ) NOT NULL AUTO_INCREMENT,
    -> `is_del` bit ( 1 ) NOT NULL DEFAULT 0 COMMENT '是否被删除',
    -> `user_id` INT ( 11 ) NOT NULL COMMENT '⽤户id',
    -> `company_id` INT ( 11 ) NOT NULL COMMENT '公司id',
    -> `publish_user_id` INT ( 11 ) NOT NULL COMMENT 'B端⽤户id',
    -> `position_id` INT ( 11 ) NOT NULL COMMENT '职位ID',
    -> `resume_type` INT ( 2 ) NOT NULL DEFAULT 0 COMMENT '简历类型:0附件 1在线',
    -> `status` VARCHAR ( 256 ) NOT NULL COMMENT '投递状态 投递状态 WAIT-待处理 AUTO_FILTER-⾃动过滤 PREPARE_CONTACT-待沟通 REFUSE-拒绝 ARRANGE_INTERVIEW-通知⾯试',
    -> `create_time` datetime NOT NULL COMMENT '创建时间',
    -> `update_time` datetime NOT NULL COMMENT '处理时间',
    -> PRIMARY KEY ( `id` ),
    -> KEY `index_userId_positionId` ( `user_id`, `position_id` ),
    -> KEY `idx_userId_operateTime` ( `user_id`, `update_time` ) 
    -> ) ENGINE = INNODB DEFAULT CHARSET = utf8mb4;
Query OK, 0 rows affected (0.01 sec)

mysql> 

查看第二组从库是否 有 lane5 和 c_order 表

~ mysql -uroot -proot
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| lane1              |
| lane2              |
| lane5              |
| lanebin            |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
8 rows in set (0.01 sec)

mysql> use lane5
mysql> show tables;
+-----------------+
| Tables_in_lane5 |
+-----------------+
| c_order         |
+-----------------+
1 row in set (0.00 sec)

mysql> 

查看第一组从库是否 有 lane3 和 c_order 表


mysql> use lane3
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
mysql> show tables;
+-----------------+
| Tables_in_lane3 |
+-----------------+
| c_order         |
+-----------------+
1 row in set (0.00 sec)

mysql> 

开始创建项目

创建 maven 项目 mysql-work

添加依赖

<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.galaxy</groupId>
    <artifactId>mysql-work</artifactId>
    <version>1.0-SNAPSHOT</version>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.9.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <description>Demo project for Spring Boot</description>
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.compile.sourceEncoding>UTF-8</project.compile.sourceEncoding>
        <shardingsphere.version>4.1.0</shardingsphere.version>
        <springboot.version>2.2.9.RELEASE</springboot.version>

    </properties>

        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-jdbc</artifactId>
                <version>${springboot.version}</version>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-data-jpa</artifactId>
                <version>${springboot.version}</version>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-data-jpa</artifactId>
                <version>2.1.6.RELEASE</version>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-test</artifactId>
                <version>${springboot.version}</version>
                <scope>test</scope>
            </dependency>
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>5.1.48</version>
            </dependency>

            <dependency>
                <groupId>org.apache.shardingsphere</groupId>
                <artifactId>sharding-jdbc-spring-boot-starter</artifactId>
                <version>${shardingsphere.version}</version>
            </dependency>
            <dependency>
                <groupId>org.apache.shardingsphere</groupId>
                <artifactId>sharding-transaction-xa-core</artifactId>
                <version>${shardingsphere.version}</version>
            </dependency>

        </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.1</version>
                <configuration>
                    <source>11</source>
                    <target>11</target>
                    <testSource>11</testSource>
                    <testTarget>11</testTarget>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

entity

package com.galaxy.entity;


import javax.persistence.*;
import java.util.Date;
/**
 * @author lane
 * @date 2021年07月27日 下午7:12
 */

@Entity
@Table(name = "c_order")
public class Order {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(name = "is_del")
    private Boolean del;

    @Column(name = "user_id")
    private Integer userId;

    @Column(name = "company_id")
    private Integer companyId;

    @Column(name = "publish_user_id")
    private Integer publishUserId;

    @Column(name = "position_id")
    private Integer positionId;

    @Column(name = "resume_type")
    private Integer resumeType;

    @Column(name = "status")
    private String status;

    @Column(name = "create_time")
    private Date createTime;

    @Column(name = "update_time")
    private Date updateTime;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public Boolean getDel() {
        return del;
    }

    public void setDel(Boolean del) {
        this.del = del;
    }

    public Integer getUserId() {
        return userId;
    }

    public void setUserId(Integer userId) {
        this.userId = userId;
    }

    public Integer getCompanyId() {
        return companyId;
    }

    public void setCompanyId(Integer companyId) {
        this.companyId = companyId;
    }

    public Integer getPublishUserId() {
        return publishUserId;
    }

    public void setPublishUserId(Integer publishUserId) {
        this.publishUserId = publishUserId;
    }

    public Integer getPositionId() {
        return positionId;
    }

    public void setPositionId(Integer positionId) {
        this.positionId = positionId;
    }

    public Integer getResumeType() {
        return resumeType;
    }

    public void setResumeType(Integer resumeType) {
        this.resumeType = resumeType;
    }

    public String getStatus() {
        return status;
    }

    public void setStatus(String status) {
        this.status = status;
    }

    public Date getCreateTime() {
        return createTime;
    }

    public void setCreateTime(Date createTime) {
        this.createTime = createTime;
    }

    public Date getUpdateTime() {
        return updateTime;
    }

    public void setUpdateTime(Date updateTime) {
        this.updateTime = updateTime;
    }

    @Override
    public String toString() {
        return "Order{" +
                "id=" + id +
                ", del=" + del +
                ", userId=" + userId +
                ", companyId=" + companyId +
                ", publishUserId=" + publishUserId +
                ", positionId=" + positionId +
                ", resumeType=" + resumeType +
                ", status='" + status + '\'' +
                ", createTime=" + createTime +
                ", updateTime=" + updateTime +
                '}';
    }
}

repository

package com.galaxy.repository;

import com.galaxy.entity.Order;
import org.springframework.data.jpa.repository.JpaRepository;

/**
 * @author lane
 * @date 2021年07月27日 下午7:14
 */
public interface OrderRepository extends JpaRepository<Order,Long> {
}

application.properties

spring.shardingsphere.datasource.names=master-0,slave-1,slave-2,master-1,slave-3,slave-4
spring.shardingsphere.props.sql.show=true

spring.shardingsphere.datasource.master-0.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.master-0.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.master-0.jdbc-url=jdbc:mysql://172.16.94.5:3306/lane3?useUnicode=true&useSSL=false
spring.shardingsphere.datasource.master-0.username=root
spring.shardingsphere.datasource.master-0.password=root

spring.shardingsphere.datasource.slave-1.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.slave-1.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.slave-1.jdbc-url=jdbc:mysql://172.16.94.6:3306/lane3?useUnicode=true&useSSL=false
spring.shardingsphere.datasource.slave-1.username=root
spring.shardingsphere.datasource.slave-1.password=root

spring.shardingsphere.datasource.slave-2.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.slave-2.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.slave-2.jdbc-url=jdbc:mysql://172.16.94.10:3306/lane3?useUnicode=true&useSSL=false
spring.shardingsphere.datasource.slave-2.username=root
spring.shardingsphere.datasource.slave-2.password=root

spring.shardingsphere.datasource.master-1.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.master-1.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.master-1.jdbc-url=jdbc:mysql://172.16.94.17:3306/lane5?useUnicode=true&useSSL=false
spring.shardingsphere.datasource.master-1.username=root
spring.shardingsphere.datasource.master-1.password=root

spring.shardingsphere.datasource.slave-3.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.slave-3.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.slave-3.jdbc-url=jdbc:mysql://172.16.94.18:3306/lane5?useUnicode=true&useSSL=false
spring.shardingsphere.datasource.slave-3.username=root
spring.shardingsphere.datasource.slave-3.password=root

spring.shardingsphere.datasource.slave-4.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.slave-4.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.slave-4.jdbc-url=jdbc:mysql://172.16.94.19:3306/lane5?useUnicode=true&useSSL=false
spring.shardingsphere.datasource.slave-4.username=root
spring.shardingsphere.datasource.slave-4.password=root

spring.shardingsphere.sharding.tables.c_order.database-strategy.inline.sharding-column=user_id
spring.shardingsphere.sharding.tables.c_order.database-strategy.inline.algorithm-expression=master-$->{user_id % 2}
spring.shardingsphere.sharding.tables.c_order.actual-data-nodes=master-$->{0..1}.c_order

spring.shardingsphere.sharding.tables.c_order.key-generator.column=id
spring.shardingsphere.sharding.tables.c_order.key-generator.type=SNOWFLAKE

spring.shardingsphere.sharding.master-slave-rules.master-0.master-data-source-name=master-0
spring.shardingsphere.sharding.master-slave-rules.master-0.slave-data-source-names=slave-1,slave-2
#spring.shardingsphere.masterslave.load-balance-algorithm-type=ROUND_ROBIN
spring.shardingsphere.sharding.master-slave-rules.master-1.master-data-source-name=master-1
spring.shardingsphere.sharding.master-slave-rules.master-1.slave-data-source-names=slave-3,slave-4

test


/**
 * @author lane
 * @date 2021年07月27日 下午7:16
 */
@RunWith(SpringRunner.class)
@SpringBootTest(classes = ShardingBootRunApplication.class)
public class ShardingTest {

    @Autowired
    private OrderRepository orderRepository;

    @org.junit.Test
    public void test(){
        for (int idx = 0; idx < 4; ++idx) {
            Order order = new Order();
            order.setCompanyId(1);

            order.setCreateTime(new Date());
            order.setDel(false);
            order.setPositionId(1);

            order.setStatus("WAITING");
            order.setPublishUserId(1);
            order.setResumeType(1);

            order.setUpdateTime(new Date());
            order.setUserId(idx);

            orderRepository.save(order);
        }


    }

    @Test
    public void testSlave(){
        List<Order> all = orderRepository.findAll();

        System.out.println(all);
    }
}

测试分库分表和主从同步结果

通过 Master1 和 Master11 的查询结果可以看出分库成功

通过 Slave1 和 Slave11 可以看到主从同步 OK

master1

mysql> select * from c_order \G;
*************************** 1. row ***************************
             id: 626865956605394944
         is_del:  
        user_id: 0
     company_id: 1
publish_user_id: 1
    position_id: 1
    resume_type: 1
         status: WAITING
    create_time: 2021-07-27 19:41:30
    update_time: 2021-07-27 19:41:30
*************************** 2. row ***************************
             id: 626865957251317760
         is_del:  
        user_id: 2
     company_id: 1
publish_user_id: 1
    position_id: 1
    resume_type: 1
         status: WAITING
    create_time: 2021-07-27 19:41:31
    update_time: 2021-07-27 19:41:31
2 rows in set (0.00 sec)

slave1


mysql> use lane3
mysql> select * from c_order \G;
*************************** 1. row ***************************
             id: 626865956605394944
         is_del:  
        user_id: 0
     company_id: 1
publish_user_id: 1
    position_id: 1
    resume_type: 1
         status: WAITING
    create_time: 2021-07-27 19:41:30
    update_time: 2021-07-27 19:41:30
*************************** 2. row ***************************
             id: 626865957251317760
         is_del:  
        user_id: 2
     company_id: 1
publish_user_id: 1
    position_id: 1
    resume_type: 1
         status: WAITING
    create_time: 2021-07-27 19:41:31
    update_time: 2021-07-27 19:41:31
2 rows in set (0.00 sec)

master11

mysql> select * from c_order \G;
*************************** 1. row ***************************
             id: 626865957129682945
         is_del:  
        user_id: 1
     company_id: 1
publish_user_id: 1
    position_id: 1
    resume_type: 1
         status: WAITING
    create_time: 2021-07-27 19:41:31
    update_time: 2021-07-27 19:41:31
*************************** 2. row ***************************
             id: 626865957284872193
         is_del:  
        user_id: 3
     company_id: 1
publish_user_id: 1
    position_id: 1
    resume_type: 1
         status: WAITING
    create_time: 2021-07-27 19:41:31
    update_time: 2021-07-27 19:41:31
2 rows in set (0.00 sec)

slave11


mysql> use lane5;
mysql> select * from c_order\G;
*************************** 1. row ***************************
             id: 626865957129682945
         is_del:  
        user_id: 1
     company_id: 1
publish_user_id: 1
    position_id: 1
    resume_type: 1
         status: WAITING
    create_time: 2021-07-27 19:41:31
    update_time: 2021-07-27 19:41:31
*************************** 2. row ***************************
             id: 626865957284872193
         is_del:  
        user_id: 3
     company_id: 1
publish_user_id: 1
    position_id: 1
    resume_type: 1
         status: WAITING
    create_time: 2021-07-27 19:41:31
    update_time: 2021-07-27 19:41:31
2 rows in set (0.00 sec)

测试读写分离结果

分别修改下 slave1 和 slave11 中 c_order 表的数据

#slave1
update c_order set status ='slave1';
#slave11
update c_order set status ='slave11';

查看读取的数据,可以看到读取到的是从库中 c_order 的数据,成功实现读写分离

[Order{id=626865956605394944, del=false, userId=0, companyId=1, publishUserId=1, positionId=1, resumeType=1, status='slave1', 
createTime=2021-07-27 19:41:30.0, updateTime=2021-07-27 19:41:30.0}, 
Order{id=626865957251317760, del=false, userId=2, companyId=1, publishUserId=1, positionId=1, resumeType=1, status='slave1',
 createTime=2021-07-27 19:41:31.0, updateTime=2021-07-27 19:41:31.0}, 
Order{id=626865957129682945, del=false, userId=1, companyId=1, publishUserId=1, positionId=1, resumeType=1, status='slave11', 
createTime=2021-07-27 19:41:31.0, updateTime=2021-07-27 19:41:31.0}, 
Order{id=626865957284872193, del=false, userId=3, companyId=1, publishUserId=1, positionId=1, resumeType=1, status='slave11', 
createTime=2021-07-27 19:41:31.0, updateTime=2021-07-27 19:41:31.0}]
2
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值