Sharding-JDBC is used to achieve C_ORDER table sub-library sub-table + read and write separation

  1. Shard c_ORDER table based on user_id
  2. Set up one master and two slave architecture for Master1 and Master2 respectively
  3. Implement read/write separation based on master1 and Master2 clusters

MySQL environment setup

MySQL installation

MySQL > install MySQL on 6 servers

  1. If the mariadb database is installed on CentOS7 by default, you may encounter unexpected problems when saving Chinese.

    yum remove mariadb-libs.x86_64
    Copy the code
  2. Download the MySql installation package

    wget http://dev.mysql.com/get/mysql-community-release-el7-5.noarch.rpm
    Copy the code
  3. Installing software Packages

    rpm -ivh mysql-community-release-el7-5.noarch.rpm
    Copy the code
  4. Install the MySQL service program

    yum install mysql-community-server
    Copy the code
  5. Restart the MySQL service

    service mysqld restart
    Copy the code

    At this point, MySQL is successfully installed on the server.

  6. Change the password

    Mysql -uroot -p mysql -uroot -p mysql -uroot -p mysql -uroot -p

    SET PASSWORD = PASSWORD('root123456');
    Copy the code
  7. MySQL: /etc/rc.local MySQL: /etc/rc.local

    /etc/init.d/mysql start
    Copy the code

After the installation is complete, try using Navicat to connect. If access is denied, you can temporarily disable the firewall:

CentOS 7.0 uses the firewall by default

Checking the Firewall Status

firewall-cmd --state
Copy the code

Stop the firewall

systemctl stop firewalld.service
Copy the code

Disable the firewall startup upon startup

systemctl disable firewalld.service 
Copy the code

1130 -host XXX is not allowed to connect to this MySQL server. The MySQL server does not support remote connection.

  1. Log in to the server and enter the database

    Mysql -uroot -p PasswordCopy the code
  2. Set the permissions

    grant all privileges on*. *to root@"%" identified by "root123456";
    Copy the code
  3. Make the configuration take effect localhost Run the following command to make the configuration take effect immediately.

    flush privileges;
    Copy the code

    It has been successfully modified and can be connected remotely through Navicat (or some other tool)

MySQL primary/secondary configuration

The Master node
Run the vi /etc/my. CNF command to modify the Master configuration file
# bin_log configuration
log_bin=mysql-bin 
Ensure that each server ID does not have the same ID
server-id=1 
sync-binlog=1 
binlog-ignore-db=information_schema 
binlog-ignore-db=mysql 
binlog-ignore-db=performance_schema 
binlog-ignore-db=sys 
# relay_log configuration
relay_log=mysql-relay-bin 
log_slave_updates=1 
relay_log_purge=0
Copy the code
Restart the service
systemctl restart mysqld
Copy the code
The master library grants authorization to the slave library

Log in to MySQL and run the following command:

mysql> grant replication slave on*. *to root@The '%' identified by 'password'; 
mysql> grant all privileges on*. *to root@The '%' identified by 'password'; 
mysql> flush privileges; Master_log_file ='mysql-bin.000007',master_log_pos=154 mysql>show master status;
Copy the code

Slave node

Modify the MySQL configuration file my. CNF of the slaves and set the server ids of the two slaves to 2 and 3 respectively

# bin_log configuration
log_bin=mysql-bin 
Ensure that each server ID does not have the same ID
server-id=2 
sync-binlog=1 
binlog-ignore-db=information_schema 
binlog-ignore-db=mysql 
binlog-ignore-db=performance_schema 
binlog-ignore-db=sys 
# relay_log configuration
relay_log=mysql-relay-bin 
log_slave_updates=1 
relay_log_purge=0 
read_only=1
Copy the code
Restart the service
systemctl restart mysqld
Copy the code
Open the synchronization

Log in to MySQL and run the MySQL command on the Slave node, for example, run the following command (note that the parameters are the same as those displayed in the show master status operation) :

change master to master_host='10.211.55.14',master_port=3306,master_user='root',master_password ='root123456',master_log_file='mysql-bin.000001',master_log_pos=120;

start slave; // Start synchronizationCopy the code

Configure semi-synchronous replication

The Master node

Log in to MySQL and run the following command to install the plug-in

install plugin rpl_semi_sync_master soname 'semisync_master.so';
show variables like '%semi%';
Copy the code

Run the vi /etc/my. CNF command to modify the MySQL configuration file

# Enable semi-synchronous replication automatically
rpl_semi_sync_master_enabled=ON 
rpl_semi_sync_master_timeout=1000
Copy the code

Restarting the MySQL service

systemctl restart mysqld
Copy the code

Slave node

Perform the following steps for both Slave nodes.

Log in to MySQL and run the following command to install the plug-in

install plugin rpl_semi_sync_slave soname 'semisync_slave.so';
Copy the code

Run the vi /etc/my. CNF command to modify the MySQL configuration file

# Enable semi-synchronous replication automatically
rpl_semi_sync_slave_enabled=ON
Copy the code

Restart the service

systemctl restart mysqld
Copy the code

Test the semi-synchronization status

Check whether semi-synchronization is enabled by checking parameters in the MySQL command line interface.

show variables like '%semi%';
Copy the code

Then check the MySQL log again.

cat /var/log/mysqld.log
Copy the code

You can view semi-synchronization information in logs, for example:

Start semi-sync binlog_dump to slave (server_id: 2), pos(mysql-bin.000005, 154)
Copy the code

Create a table

Create the database and order tables by manipulating the main library

Create database test_db:

create database test_db;
Copy the code

Create order table c_order:

use test_db;

CREATE TABLE `c_order`(
 `id` bigint(20) NOT NULL AUTO_INCREMENT,
 `is_del` bit(1) NOT NULL DEFAULT 0 COMMENT 'Deleted or not'.`user_id` int(11) NOT NULL COMMENT 'user id'.`company_id` int(11) NOT NULL COMMENT 'the company id'.`publish_user_id` int(11) NOT NULL COMMENT 'User ID of user B'.`position_id` int(11) NOT NULL COMMENT 'job ID'.`resume_type` int(2) NOT NULL DEFAULT 0 COMMENT 'Resume type: 0 Attachment 1 online'.`status` varchar(256) NOT NULL COMMENT 'Post status Post status WAIT- to be processed AUTO_FILTER- PREPARE_CONTACT- to be communicated REFUSE- ARRANGE_INTERVIEW- Notify interview'.`create_time` datetime NOT NULL COMMENT 'Creation time'.`update_time` datetime NOT NULL COMMENT 'Processing time',
 PRIMARY KEY (`id`),
 KEY `index_userId_positionId` (`user_id`.`position_id`),
 KEY `idx_userId_operateTime` (`user_id`.`update_time`))ENGINE = InnoDB DEFAULT CHARSET = utf8mb4;
Copy the code

The slave library is replicated and the order table created in the master library can be queried:

use test_db;
SHOW TABLES;
Copy the code

Set up the project

Create project Sharding-jDBC-demo

Source code address: github.com/sixj0/shard…


      
<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.0</modelVersion>

    <groupId>com.sixj</groupId>
    <artifactId>sharding-jdbc-demo</artifactId>
    <version>0.0.1 - the SNAPSHOT</version>
    <name>sharding-jdbc-demo</name>
    <description>Sharding-JDBC implementation of sub-database sub-table and read and write separation</description>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
        <spring-cloud.version>Dalston.SR1</spring-cloud.version>
        <spring-boot.version>2.2.5. RELEASE</spring-boot.version>
        <mysql-connector.version>5.1.48</mysql-connector.version>
        <shardingsphere.version>4.1.0</shardingsphere.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
            <version>${spring-boot.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
            <version>${spring-boot.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <version>${spring-boot.version}</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>${mysql-connector.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.shardingsphere</groupId>
            <artifactId>sharding-jdbc-spring-boot-starter</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>1.8</source>
                    <target>1.8</target>
                    <testSource>1.8</testSource>
                    <testTarget>1.8</testTarget>
                </configuration>
            </plugin>
        </plugins>
    </build>



</project>
Copy the code

Configuration information:

Data source information for six databases
spring.shardingsphere.datasource.names=master1,slave1,slave2,master2,slave3,slave4

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: / / 10.211.55.14:3306 / test_db? useUnicode=true&characterEncoding=utf-8&useSSL=false
spring.shardingsphere.datasource.master1.username=root
spring.shardingsphere.datasource.master1.password=root123456

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: / / 10.211.55.16:3306 / test_db? useSSL=false
spring.shardingsphere.datasource.slave1.username=root
spring.shardingsphere.datasource.slave1.password=root123456

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: / / 10.211.55.17:3306 / test_db? useSSL=false
spring.shardingsphere.datasource.slave2.username=root
spring.shardingsphere.datasource.slave2.password=root123456

spring.shardingsphere.datasource.master2.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.master2.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.master2.jdbc-url=JDBC: mysql: / / 10.211.55.15:3306 / test_db? useUnicode=true&characterEncoding=utf-8&useSSL=false
spring.shardingsphere.datasource.master2.username=root
spring.shardingsphere.datasource.master2.password=root123456

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: / / 10.211.55.18:3306 / test_db? useSSL=false
spring.shardingsphere.datasource.slave3.username=root
spring.shardingsphere.datasource.slave3.password=root123456

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: / / 10.211.55.19:3306 / test_db? useSSL=false
spring.shardingsphere.datasource.slave4.username=root
spring.shardingsphere.datasource.slave4.password=root123456
#id uses the snowflake algorithm
spring.shardingsphere.sharding.tables.c_order.key-generator.column=id
spring.shardingsphere.sharding.tables.c_order.key-generator.type=SNOWFLAKE
#sharding-database-table shards c_order table based on user_id
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 + 1}
spring.shardingsphere.sharding.tables.c_order.actual-data-nodes=master$->{1.. 2}.c_order
Master-slave Implements read/write separation based on master1 and master2 clusters
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
spring.shardingsphere.sharding.master-slave-rules.master2.master-data-source-name=master2
spring.shardingsphere.sharding.master-slave-rules.master2.slave-data-source-names=slave3,slave4
# Load balancing for multiple slave libraries
spring.shardingsphere.masterslave.load-balance-algorithm-type=ROUND_ROBIN
Print to execute SQL
spring.shardingsphere.props.sql.show=true
Copy the code

Entity class:

@Entity
@Table(name = "c_order")
public class COrder implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long id;

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

    @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;
}
Copy the code

Order table Repository:

public interface COrderRepository extends JpaRepository<COrder.Long> {}Copy the code

The test class:

@SpringBootTest(classes = ShardingJdbcDemoApplication.class)
class ShardingJdbcDemoApplicationTests {

    @Autowired
    private COrderRepository cOrderRepository;
		
  	/** * generates 20 records */
    @Test
    public void testAdd(a) {
        for (int i = 100; i <120; i++) {
            COrder cOrder = new COrder();
            cOrder.setDel(false);
            cOrder.setUserId(i);
            cOrder.setCompanyId(new Random().nextInt(10));
            cOrder.setPublishUserId(new Random().nextInt(10));
            cOrder.setPositionId(new Random().nextInt(10));
            cOrder.setResumeType(new Random().nextInt(1));
            cOrder.setStatus("ARRANGE_INTERVIEW");
            cOrder.setCreateTime(new Date());
            cOrder.setUpdateTime(newDate()); cOrderRepository.saveAndFlush(cOrder); }}@Test
    public void testFind(a) { List<COrder> cOrderList = cOrderRepository.findAll(); cOrderList.forEach(cOrder -> { System.out.println(cOrder.toString()); }); }}Copy the code

Execution effect:

User_id in Master1 is even

The user_id in Master2 is odd

Read data from Master1’s slave library and Master2’s slave library when querying all records