ShardingJDBC实现分库以及读写分离架构搭建

ShardingJDBC实现分库以及读写分离架构搭建

一、环境软件版本

环境&软件 版本
虚拟机&VMware Fusion 12.1
服务器&CentOS 7.8
数据库&Mysql 5.7.28
远程连接&SSH Shell 16.03

二、环境架构介绍

机器名称 IP 角色
Mysql_Master1 192.168.91. 可读写、主库
Mysql_Slave1 192.168.91.135 只读、Master1从库
Mysql_Slave2 192.168.91.136 只读、Master1从库
Mysql_Master0 192.168.91.134 可读写、主库
Mysql_Slave3 192.168.91.135 只读、Master0从库
Mysql_Slave4 192.168.91.136 只读、Master0从库

三、MySQL安装(一主两从)

1. 下载mysql5.7.78

可以通过wget下载:
wget https://cdn.mysql.com/archives/mysql-5.7/mysql-5.7.28-1.el7.x86_64.rpm-bundle.tar
已下载可通过scp传输:
scp -r mysql-5.7.28-1.el7.x86_64.rpm-bundle.tar root@192.168.91.135:/usr/local/software

2. 移除linux自带的mariadb,避免安装时会产生冲突

rpm -qa|grep mariadb
rpm -e mariadb-libs-5.5.68-1.el7.x86_64 --nodeps 

3. 安装mysql

tar xvf mysql-5.7.28-1.el7.x86_64.rpm-bundle.tar 
rpm -ivh mysql-community-common-5.7.28-1.el7.x86_64.rpm
rpm -ivh mysql-community-libs-5.7.28-1.el7.x86_64.rpm
rpm -ivh mysql-community-libs-compat-5.7.28-1.el7.x86_64.rpm 
rpm -ivh mysql-community-client-5.7.28-1.el7.x86_64.rpm
rpm -ivh mysql-community-server-5.7.28-1.el7.x86_64.rpm --nodeps 
rpm -ivh mysql-community-devel-5.7.28-1.el7.x86_64.rpm 

4. 初始化用户并查看密码

mysqld --initialize --user=mysql
cat /var/log/mysqld.log | grep password

5. 启动mysql并设置开机启动

systemctl start mysqld
systemctl enable mysqld

6. 登录mysql并修改密码

mysql -uroot -p{cat查看的初始密码}
set password for root@localhost = password('123456');

7.登录Mysql,授权其他机器访问

grant all privileges on *.* to 'root'@'%' identified by 'root';
flush privileges;

四、主从同步配置

1.主库配置

1. 修改配置文件
vim /etc/my.cnf

-----------------------------------追加配置内容:
#bin_log配置
log_bin=mysql-bin
server-id=1
sync-binlog=1
# 忽略database库设置
binlog-ignore-db=information_schema
binlog-ignore-db=mysql
binlog-ignore-db=performance_schema
binlog-ignore-db=sys
#relay_log配置
relay_log=mysql-relay-bin
log_slave_updates=1
relay_log_purge=0
#gtid配置
#开启gtid
#gtid_mode=on
#enforce_gtid_consistency=1
-----------------------------------配置文件完成

2. 重启mysql
systemctl restart mysqld 

3. 授权同步
grant replication slave on *.* to 'root'@'%' identified by 'root';
flush privileges;

4. 查看主库状态
show master status;
+------------------+----------+--------------+-------------------------------------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB                                | Executed_Gtid_Set |
+------------------+----------+--------------+-------------------------------------------------+-------------------+
| mysql-bin.000001 |     1398 |              | information_schema,mysql,performance_schema,sys |                   |
+------------------+----------+--------------+-------------------------------------------------+-------------------+

2.从库配置

1. 修改配置文件:
vim /etc/my.cnf

-----------------------------------追加配置内容:
#bin_log配置
log_bin=mysql-bin
#服务器ID,从库1是2,从库2是3server-id=2
server-id=2

sync-binlog=1
# 忽略database库设置
binlog-ignore-db=information_schema
binlog-ignore-db=mysql
binlog-ignore-db=performance_schema
binlog-ignore-db=sys

#relay_log配置
relay_log=mysql-relay-bin
log_slave_updates=1
relay_log_purge=0
read_only=1

#gtid配置
#开启gtid
#gtid_mode=on
#enforce_gtid_consistency=1
-----------------------------------配置文件完成

2. 重启mysql:systemctl restart mysqld 

3. 设置连接的主库信息并开启slave

change master to master_host='192.168.91.134',master_port=3306,master_user='root',master_password='123456'
,master_log_file='mysql-bin.000001',master_log_pos=1398;

start slave;

此时主从复制已完成,主库的增删改可以同步到从库

3. 建表SQL

CREATE TABLE `c_order`  (
  `id` bigint(20) NOT NULL,
  `user_id` bigint(20) NULL,
  `company_id` bigint(20) NULL,
  `position_id` bigint(20) NULL,
  `resume_type` int(11) NULL,
  `status` tinyint(1) NULL,
  `create_time` datetime(0) NULL,
  `update_time` datetime(0) NULL,
  `description` varchar(255) NULL,
  PRIMARY KEY (`id`)
) ENGINE = InnoDB CHARACTER SET = utf8mb4;

五、java工程

1. maven依赖

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

<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-test</artifactId>
	<version>${springboot.version}</version>
	<scope>test</scope>
</dependency>

<dependency>
	<groupId>mysql</groupId>
	<artifactId>mysql-connector-java</artifactId>
	<version>5.1.35</version>
</dependency>
<dependency>
	<groupId>org.apache.shardingsphere</groupId>
	<artifactId>sharding-jdbc-spring-boot-starter</artifactId>
	<version>${shardingsphere.version}</version>
</dependency>

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-data-jpa</artifactId>
	<version>${springboot.version}</version>
</dependency>

2. 配置文件(分片规则)

# 显示执行SQL
spring.shardingsphere.props.sql.show=true
# 显示依赖
spring.shardingsphere.props.sql.show=true
#datasource
spring.shardingsphere.datasource.names=master0,master1,slave1,slave2,slave3,slave4

spring.shardingsphere.datasource.master0.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.master0.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.master0.jdbc-url=jdbc:mysql://192.168.91.3:3306/dayu
spring.shardingsphere.datasource.master0.username=root
spring.shardingsphere.datasource.master0.password=123456

spring.shardingsphere.datasource.master1.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.master1.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.master1.jdbc-url=jdbc:mysql://192.168.91.5:3306/dayu
spring.shardingsphere.datasource.master1.username=root
spring.shardingsphere.datasource.master1.password=123456


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.91.2:3306/dayu
spring.shardingsphere.datasource.slave1.username=root
spring.shardingsphere.datasource.slave1.password=123456

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.91.4:3306/dayu
spring.shardingsphere.datasource.slave2.username=root
spring.shardingsphere.datasource.slave2.password=123456

spring.shardingsphere.datasource.slave3.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.slave3.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.slave3.jdbc-url=jdbc:mysql://192.168.91.6:3306/dayu
spring.shardingsphere.datasource.slave3.username=root
spring.shardingsphere.datasource.slave3.password=123456

spring.shardingsphere.datasource.slave4.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.slave4.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.slave4.jdbc-url=jdbc:mysql://192.168.91.7:3306/dayu
spring.shardingsphere.datasource.slave4.username=root
spring.shardingsphere.datasource.slave4.password=123456

#sharding-database默认配置
spring.shardingsphere.sharding.default-database-strategy.inline.sharding-column=id
spring.shardingsphere.sharding.default-database-strategy.inline.algorithm-expression=master$->{id % 2}

#sharding-tables
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.key-generator.column=id
spring.shardingsphere.sharding.tables.c_order.key-generator.type=SNOWFLAKE
        
#主从配置
spring.shardingsphere.sharding.master-slave-rules.master0.master-data-source-name=master0
spring.shardingsphere.sharding.master-slave-rules.master0.slave-data-source-names=slave3,slave4
spring.shardingsphere.sharding.master-slave-rules.master1.master-data-source-name=master1
spring.shardingsphere.sharding.master-slave-rules.master1.slave-data-source-names=slave1,slave2

3. 映射类以及操作类

3.1 实体类Order

package com.dayu.shardingsphere.entity;


import javax.persistence.*;

@Entity
@Table(name = "c_order")
public class Order {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    @Column(name = "user_id")
    private Long userId;
    @Column(name = "company_id")
    private Long companyId;
    @Column(name = "position_id")
    private Long positionId;
    @Column(name = "description")
    private String description;

    public Long getId() {
        return id;
    }

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

    public Long getUserId() {
        return userId;
    }

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

    public Long getCompanyId() {
        return companyId;
    }

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

    public Long getPositionId() {
        return positionId;
    }

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

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    @Override
    public String toString() {
        return "Order{" +
                "id=" + id +
                ", userId=" + userId +
                ", companyId=" + companyId +
                ", positionId=" + positionId +
                ", description='" + description + '\'' +
                '}';
    }
}

3.2 mapper类

package com.dayu.shardingsphere.repository;

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

public interface OrderRepository extends JpaRepository<Order,Long> {
}

4. 测试类

package com.dayu.shardingsphere;

import com.dayu.shardingsphere.entity.Order;
import com.dayu.shardingsphere.repository.OrderRepository;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import javax.annotation.Resource;
import java.util.List;
import java.util.Random;

@RunWith(SpringRunner.class)
@SpringBootTest(classes = ShardingsphereApplication.class)
public class TestShardingDatabase {

    @Resource
    private OrderRepository orderRepository;

    @Test
    public void testAdd() {
        Random random = new Random();
        for (int i = 1; i <= 20; i++) {
            Order order = new Order();
            order.setCompanyId(random.nextLong());
            order.setPositionId(Math.abs(random.nextLong()));
            order.setUserId(Math.abs(random.nextLong()));
            order.setDescription("this is " + i + " record");
            orderRepository.save(order);
        }
    }

    @Test
    public void testSelect() {
        List<Order> all = orderRepository.findAll();
        all.forEach(System.out::println);
    }

}

5. 测试结果

5.1 运行testAdd方法

可以看到实际执行的sql根据user_id取模后存入到对应的库中
ShardingJDBC实现分库以及读写分离架构搭建

5.2 运行testSelect方法

可以看到实际执行的sql分发到从库中执行
ShardingJDBC实现分库以及读写分离架构搭建

上一篇:CSS学习笔记:定位属性position


下一篇:11.1CSS样式