ShardingSphere读写分离相关

本系列Spring Boot 版本 3.1.0

本系列ShardingSphere 版本 5.4.0

Spring Boot基础依赖:

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

Mybatis Plus

		<dependency>
			<groupId>com.baomidou</groupId>
			<artifactId>mybatis-plus-spring-boot3-starter</artifactId>
			<version>3.5.5</version>
		</dependency>
		<dependency>
			<groupId>com.mysql</groupId>
			<artifactId>mysql-connector-j</artifactId>
			<scope>runtime</scope>
		</dependency>

ShardingSphere5.3.0及之后的版本,考虑到维护兼容成本,更加专心于自身功能迭代,移除了Spring Boot Starter,所以只能引入 ShardingSphere-JDBC核心包:

		<dependency>
			<groupId>org.apache.shardingsphere</groupId>
			<artifactId>shardingsphere-jdbc-core</artifactId>
			<version>5.4.0</version>
		</dependency>
		<!--java.lang.ClassNotFoundException: com.sun.xml.internal.bind.v2.ContextFactory-->
		<dependency>
			<groupId>org.glassfish.jaxb</groupId>
			<artifactId>jaxb-runtime</artifactId>
			<version>2.3.8</version>
		</dependency>

ShardingSphere-JDBC5.3.0及之后的版本不再提供Spring Boot Starter,所以配置方面有较大的变化,目前只支持Java APIYAML 进行配置。

ShardingSphere 提供了 JDBC 驱动,首先需要在application.yml中配置ShardingSphereDriver ,并指定YAML配置文件地址:

server:
  port: 8080
spring:
  datasource:
    # 配置 DataSource Driver
    driver-class-name: org.apache.shardingsphere.driver.ShardingSphereDriver
    # 指定 YAML 配置文件
    url: jdbc:shardingsphere:classpath:readwrite-splitting-config.yml # 读写分离配置文件

application.yml同级目录下创建readwrite-splitting-config.yml续写分离配置文件,在该文件中,首先添加数据源配置:

# 数据源配置
dataSources:
  # 主库
  write_ds: # 逻辑名称
    dataSourceClassName: com.zaxxer.hikari.HikariDataSource
    driverClassName: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://192.168.56.101:3306/test
    username: root
    password: "root"
  # 从库1
  read_ds_0:
    dataSourceClassName: com.zaxxer.hikari.HikariDataSource
    driverClassName: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://192.168.56.101:3307/test
    username: root
    password: "root"
  # 从库2
  read_ds_1:
    dataSourceClassName: com.zaxxer.hikari.HikariDataSource
    driverClassName: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://192.168.56.101:3308/test
    username: root
    password: "root"

然后添加读写分离规则、从库负载均衡相关配置:

# 规则配置
rules:
  # 读写分离配置
  - !READWRITE_SPLITTING
    dataSources: # 数据源
      readwrite_ds: # 读写分离逻辑数据源名称
        writeDataSourceName: write_ds # 写库数据源名称
        readDataSourceNames: # 读库数据源名称,多个从数据源用逗号分隔
          - read_ds_0
          - read_ds_1
        transactionalReadQueryStrategy: PRIMARY # 事务内读请求的路由策略,可选值:PRIMARY(路由至主库)、FIXED(同一事务内路由至固定数据源)、DYNAMIC(同一事务内路由至非固定数据源)。默认值:DYNAMIC
        loadBalancerName: read # 负载均衡自定义算法名称
    # 负载均衡算法
    loadBalancers:
      read:  # 自定义的算法名称
        type: RANDOM # 负载均衡算法类型
props:
  # 是否打印 SQL
  sql-show: true

负载均衡(Load Balancing)用于将工作负载分配到多个计算资源,以提高性能、可靠性、可扩展性。读写分离环境下,对于多台从库的访问策略,ShardingSphere内置了多种负载均衡算法,满足用户绝大多数业务场景的需要

轮询

按顺序轮流对读库进行访问。

# 规则配置
rules:
  # 读写分离配置
  - !READWRITE_SPLITTING
    dataSources: # 数据源
      readwrite_ds: # 读写分离逻辑数据源名称
        writeDataSourceName: write_ds # 写库数据源名称
        readDataSourceNames: # 读库数据源名称,多个从数据源用逗号分隔
          - read_ds_0
          - read_ds_1
        transactionalReadQueryStrategy: PRIMARY # 事务内读请求的路由策略,可选值:PRIMARY(路由至主库)、FIXED(同一事务内路由至固定数据源)、DYNAMIC(同一事务内路由至非固定数据源)。默认值:DYNAMIC
        loadBalancerName: read # 负载均衡自定义算法名称
    # 负载均衡算法
    loadBalancers:
      read:  # 自定义的算法名称
        type: ROUND_ROBIN # 负载均衡算法类型
随机

随机选取一台读库进行访问。

# 规则配置
rules:
  # 读写分离配置
  - !READWRITE_SPLITTING
    dataSources: # 数据源
      readwrite_ds: # 读写分离逻辑数据源名称
        writeDataSourceName: write_ds # 写库数据源名称
        readDataSourceNames: # 读库数据源名称,多个从数据源用逗号分隔
          - read_ds_0
          - read_ds_1
        transactionalReadQueryStrategy: PRIMARY # 事务内读请求的路由策略,可选值:PRIMARY(路由至主库)、FIXED(同一事务内路由至固定数据源)、DYNAMIC(同一事务内路由至非固定数据源)。默认值:DYNAMIC
        loadBalancerName: read # 负载均衡自定义算法名称
    # 负载均衡算法
    loadBalancers:
      read:  # 自定义的算法名称
        type: RANDOM # 负载均衡算法类型
权重

给读库分配权重,权重高的优先访问。

# 规则配置
rules:
  # 读写分离配置
  - !READWRITE_SPLITTING
    dataSources: # 数据源
      readwrite_ds: # 读写分离逻辑数据源名称
        writeDataSourceName: write_ds # 写库数据源名称
        readDataSourceNames: # 读库数据源名称,多个从数据源用逗号分隔
          - read_ds_0
          - read_ds_1
        transactionalReadQueryStrategy: PRIMARY # 事务内读请求的路由策略,可选值:PRIMARY(路由至主库)、FIXED(同一事务内路由至固定数据源)、DYNAMIC(同一事务内路由至非固定数据源)。默认值:DYNAMIC
        loadBalancerName: read # 负载均衡自定义算法名称
    # 负载均衡算法
    loadBalancers:
      read:  # 自定义的算法名称
        type: WEIGHT # 负载均衡算法类型
        # 属性
        props:
          # 属性名使用读库名称,参数填写读库对应的权重值。权重参数范围最小值 > 0,合计 <= Double.MAX_VALUE。
          # 读库名称: 权重
          read_ds_0: 9
          read_ds_1: 1
自定义

考虑到业务场景的复杂性,提供基于SPI 接口实现符合自己业务需要的负载均衡算法。

ShardingSphere提供了读库负载均衡算法接口ReadQueryLoadBalanceAlgorithm,用户根据自定的算法返回一个可访问的读库。

public interface ReadQueryLoadBalanceAlgorithm extends ShardingSphereAlgorithm {

     /**
     *
     * @param name 读写分离逻辑数据源名称
     * @param writeDataSourceName 写库数据源名称
     * @param readDataSourceNames 读库数据源名称集合
     * @return 命中的读库名称
     */
    String getDataSource(String name, String writeDataSourceName, List<String> readDataSourceNames) {
    
    }

实现ReadQueryLoadBalanceAlgorithm接口,自定义一个负载均衡算法:

public final class CustomReadQueryLoadBalanceAlgorithm implements ReadQueryLoadBalanceAlgorithm {

    /**
     * 配置类中的props属性
     *     # 负载均衡算法
     *     loadBalancers:
     *       read:  # 自定义的算法名称
     *         type: CUSTOM # 负载均衡算法类型
     *         # 属性
     *         props:
     *           # 属性名使用读库名称,参数填写读库对应的权重值。权重参数范围最小值 > 0,合计 <= Double.MAX_VALUE。
     *           # 读库名称: 权重
     *           read_ds_0: 9
     *           read_ds_1: 1
     */
    private Properties props;
    
    // 将配置类props属性赋值给当前对象 
    public void init(Properties props) {
        this.props = props;
    }

    public String getDataSource(String name, String writeDataSourceName, List<String> readDataSourceNames) {
        // 自定义算法逻辑(这里演示,直接返回第一个)
        return readDataSourceNames.get(0);
    }

    /**
     * 声明算法类型
     */
    public String getType() {
        return "CUSTOM";
    }

    /**
     * 是否是默认
     */
    public boolean isDefault() {
        return false;
    }

    public Properties getProps() {
        return props;
    }

    public void setProps(Properties props) {
        this.props = props;
    }
}

resources目录下创建META-INF\services文件夹,并创建文件,名称为org.apache.shardingsphere.readwritesplitting.spi.ReadQueryLoadBalanceAlgorithm,文件内容为自定义算法类全限定类名:

com.pearl.shardingsphere.rw.algorithm.CustomReadQueryLoadBalanceAlgorithm

配置类修改算法类型为自定义:

# 规则配置
rules:
  # 读写分离配置
  - !READWRITE_SPLITTING
    dataSources: # 数据源
      readwrite_ds: # 读写分离逻辑数据源名称
        writeDataSourceName: write_ds # 写库数据源名称
        readDataSourceNames: # 读库数据源名称,多个从数据源用逗号分隔
          - read_ds_0
          - read_ds_1
        transactionalReadQueryStrategy: PRIMARY # 事务内读请求的路由策略,可选值:PRIMARY(路由至主库)、FIXED(同一事务内路由至固定数据源)、DYNAMIC(同一事务内路由至非固定数据源)。默认值:DYNAMIC
        loadBalancerName: read # 负载均衡自定义算法名称
    # 负载均衡算法
    loadBalancers:
      read:  # 自定义的算法名称
        type: CUSTOM # 负载均衡算法类型

### ShardingSphere 中实现读写分离 #### 配置文件设置 为了在 ShardingSphere 5.5.1 版本中配置读写分离,需调整 `application.yml` 文件中的相应参数。具体来说,在 Spring Boot 应用程序中通过定义数据源以及读写分离规则来达成目标[^1]。 ```yaml spring: shardingsphere: datasource: names: master,slave_0,slave_1 master: type: com.zaxxer.hikari.HikariDataSource driver-class-name: com.mysql.cj.jdbc.Driver jdbc-url: jdbc:mysql://localhost:3306/master_db?serverTimezone=UTC&useSSL=false username: root password: root slave_0: type: com.zaxxer.hikari.HikariDataSource driver-class-name: com.mysql.cj.jdbc.Driver jdbc-url: jdbc:mysql://localhost:3307/slave_db_0?serverTimezone=UTC&useSSL=false username: root password: root slave_1: type: com.zaxxer.hikari.HikariDataSource driver-class-name: com.mysql.cj.jdbc.Driver jdbc-url: jdbc:mysql://localhost:3308/slave_db_1?serverTimezone=UTC&useSSL=false username: root password: root rules: readwrite-splitting: data-sources: ds_0: static-strategy: write-data-source-name: master read-data-source-names: slave_0,slave_1 ``` 上述 YAML 配置展示了如何指定主数据库 (`master`) 和两个从属副本 (`slave_0`, `slave_1`) 来支持读取负载均衡。对于每一个读请求,ShardingSphere 将自动选择其中一个可用的只读实例执行查询;而对于所有的写入操作,则始终定向到主节点处理[^2]。 #### 测试代码验证 下面是一个简单的测试类用于检验读写分离功能是否正常工作: ```java @SpringBootTest class ShardingsphereJdbcDemoApplicationTests { @Resource private UserMapper userMapper; @Test public void contextLoads() { } @Test void testInsertUser(){ User user = new User(); user.setUname("test_user"); int result = userMapper.insert(user); System.out.println(result>0?"插入成功":"插入失败"); } } ``` 此段 Java 测试案例创建了一个新的用户记录并尝试将其保存至数据库中。如果一切顺利的话,这条新纪录应该会被发送给主服务器进行存储[^5]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值