ShardingSphere-ShardingJdbc read-write separation

1. Read and write separate background

Although sub-databases and sub-tables can optimize database operations, to achieve high concurrency, a master-slave architecture has emerged. The master-slave replication architecture of the database locates the write operation of the database to the master database. The master database and the slave database maintain data consistency through asynchronous and semi-synchronous replication. All read operations are performed on the N slave libraries of the main library. Through load balancing, each query will evenly fall on each slave database.

One master n slaves, do read and write separation (data is written to the master database, the master database data is synchronized to the slave database through the mysql data synchronization mechanism -> the program reads the slave database data), and multiple slave libraries can achieve load balancing. Secondly, ShardingSphere-ShardingJdbc can manually force part of the read request to the main library. (Because the master-slave synchronization is delayed, for systems with high real-time requirements, some read requests can also be sent to the main library)
MySQL configuration master-slave synchronization can refer to another blog: https://blog.csdn.net/u014553029/ article/details/108832268

Two, read and write separation realization

2.1 Environmental preparation

Program environment: SpringBoot+MyBatis-plus
database environment:

Database ip database effect
127.0.0.1 ShardingSphere master
127.0.0.1 ShardingSphere1 slave1
127.0.0.1 ShardingSphere2 slave2

2.2 Add ShardingSphere dependency

<!--shardingsphere数据分片、脱敏工具-->
<dependency>
    <groupId>org.apache.shardingsphere</groupId>
    <artifactId>sharding-jdbc-spring-boot-starter</artifactId>
    <version>4.1.0</version>
</dependency>

2.3 Configure read-write separation rules

#### spring  ####
spring:
  # 配置说明地址 https://shardingsphere.apache.org/document/legacy/4.x/document/cn/manual/sharding-jdbc/configuration/config-spring-boot/#%E6%95%B0%E6%8D%AE%E5%88%86%E7%89%87
  shardingsphere:
    # 数据库
    datasource:
      # 数据库的别名
      names: ds0,ds1,ds2
      # 主库1 ,master数据库
      ds0:
        ###  数据源类别
        type: com.alibaba.druid.pool.DruidDataSource
        driverClassName: com.mysql.cj.jdbc.Driver
        url: jdbc:mysql://146.56.192.87:3306/shardingsphere?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&serverTimezone=GMT%2B8
        username: oyc
        password: oyc@123456
      # 从库1 ,slave数据库
      ds1:
        ###  数据源类别
        type: com.alibaba.druid.pool.DruidDataSource
        driverClassName: com.mysql.cj.jdbc.Driver
        url: jdbc:mysql://146.56.192.87:3306/shardingsphere1?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&serverTimezone=GMT%2B8
        username: oyc
        password: oyc@123456
      # 从库2 ,slave数据库
      ds2:
        ###  数据源类别
        type: com.alibaba.druid.pool.DruidDataSource
        driverClassName: com.mysql.cj.jdbc.Driver
        url: jdbc:mysql://146.56.192.87:3306/shardingsphere2?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&serverTimezone=GMT%2B8
        username: oyc
        password: oyc@123456

    # *** 数据库分库分表配置 start
    masterslave:
      # 查询时的负载均衡算法,目前有2种算法,round_robin(轮询)和random(随机),
      # 算法接口是io.shardingjdbc.core.api.algorithm.masterslave.MasterSlaveLoadBalanceAlgorithm。
      # 实现类有RandomMasterSlaveLoadBalanceAlgorithm 和 RoundRobinMasterSlaveLoadBalanceAlgorithm。
      load-balance-algorithm-type: round_robin
      name: dataSource
      # 主数据源名称
      master-data-source-name: ds0
      # 从数据源名称,多个用逗号隔开
      slave-data-source-names: ds1,ds2
    # *** 数据库分库分表配置 end

    props:
      # 打印SQL
      sql.show: true
      check:
        table:
          metadata: true
          # 是否在启动时检查分表元数据一致性
          enabled: true
      query:
        with:
          cipher:
            column: true

2.4 Test the separation effect of reading and writing

(1) Write data, all write to the main library:

Read and write separation effect-write data

(2) Read data, select and read from the library according to the rule load;

Read and write separation effect-read data

2.5 Force reading of main library data

Solution to the read delay problem:
  Just insert a piece of data, and then read it right away, may it not be read at this time? In the final analysis, it is because the data is copied to the slave node after the master node is written. The reason why the data cannot be read is that the copying time is relatively long, that is to say, the data has not been copied to the slave node, you have to read from the node I can’t read it. The master-slave replication of mysql5.7 is multi-threaded, which means that the speed will become faster, but it may not be guaranteed to be read 100% immediately. We can solve this problem in two ways:
  (1) Business-level compromise, whether Reading will be performed immediately after the operation is completed
  (2) For those that must be read out immediately after the operation and cannot be compromised in business, we can directly go to the main library for this type of reading. Of course, Sharding-JDBC also takes this issue into consideration. Exist, so we provide us with a function that allows users to specify whether to use the main library for reading. Use the following method to set up before reading:

/**
 * 用户列表,强制路由主库
 */
@RequestMapping("ds0")
public List<User> userListDs0() {
    logger.info("********TestController userListDs0():强制路由主库");

    HintManager hintManager = HintManager.getInstance();
    List<User> users = userMapper.selectList(null);

    //清除分片键值,分片键值保存在ThreadLocal中,所以需要在操作结束时调用hintManager.close()来清除ThreadLocal中的内容。hintManager实现了AutoCloseable接口,可推荐使用try with resource自动关闭。
    hintManager.close();
    List<User> users1 = userMapper.selectList(null);
    users.addAll(users1);
    return users;
}

Mandatory routing to the main library:
Force routing to the main library
Mandatory reading of the main library Results:
Force to read the contents of the main library
As can be seen from the above figure, after we set the mandatory reading of the main library, each query is to obtain the data of the main library.

Official website portal: https://shardingsphere.apache.org/document/legacy/4.x/document/cn/manual/sharding-jdbc/usage/read-write-splitting/
Source portal: https://github. com/oycyqr/springboot-learning-demo/tree/master/springboot-shardingsphere-load

Guess you like

Origin blog.csdn.net/u014553029/article/details/109276059