ShardingSphere5.x.x(最新版)配置MySQL读写分离

ShardingSphere5.x.x(最新版)配置MySQL读写分离

使用ShardingSphere-JDBC配置项目的读写分离(仅包含ShardingSphere-JDBC相关配置内容)
作者这里使用springboot2.x.x整合ShardingSphere-JDBC实现读写分离,注意的是,作者使用的springboot版本是2.7.10,支持ShardingSphere 5.2.x和ShardingSphere 5.3.x的配置,注意的是如果使用springboot3.0以上的版本,可能只有ShardingSphere 5.3.x支持。

1. ShardingSphere 5.2.x

5.3.0 版本以前,ShardingSphere-JDBC 同时支持 Java APIYAMLSpring Boot StarterSpring Namespace 等配置方式。

因此可以使用shardingsphere-jdbc-core-spring-boot-starter进行配置,本节使用starter 5.2.1进行项目配置。
ShardingSphere其他相关介绍查看其他博客文章。

可以参考官方文档:ShardingSphere 5.2.1 文档

切记,需要选择合适的版本

官方文档

1.1 引入依赖坐标

引入starter坐标的最后一个版本(官方不再维护starter版本)

<dependency>
    <groupId>org.apache.shardingsphere</groupId>
    <artifactId>shardingsphere-jdbc-core-spring-boot-starter</artifactId>
    <version>5.2.1</version>
</dependency>

覆盖springboot2.x的SnakeYAML依赖,如果你是sringboot3.x,可能不需要,作者没有尝试。
原因参考github上的Issues:https://github.com/apache/shardingsphere/issues/21476

在这里插入图片描述

引入依赖覆盖springboot默认版本

<dependency>
    <groupId>org.yaml</groupId>
    <artifactId>snakeyaml</artifactId>
    <version>1.33</version>
</dependency>

1.2 在springboot配置文件中做相应的配置

参考官方文档,记得选对应版本:Spring Boot Starter 配置
在这里插入图片描述

1.2.1 数据源配置

注意,使用数据源配置需要去掉所有spring.datasource下的所有配置

并且,数据源的starter坐标可能出现问题,例如druid的starter坐标,参考github上的常见问题:https://github.com/apache/shardingsphere/wiki/FAQ#jdbc

在这里插入图片描述

官网常见问题内容少于项目开源的github上的常见问题,建议遇到问题前往github查看或者提问,提问请符合官方提问模板并使用英语提问。

因此,我们下面使用druid配置,因此需要导入druid的非starter依赖

<!-- 禁用druid的starter依赖 -->
<!--<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid-spring-boot-starter</artifactId>
    <version>1.2.16</version>
</dependency>-->
<!-- 使用ShardingSphere读写分离不能使用druid的starter -->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid</artifactId>
    <version>1.2.18</version>
</dependency>

配置参考官方文档:

spring.shardingsphere.datasource.names= # 真实数据源名称,多个数据源用逗号区分

# <actual-data-source-name> 表示真实数据源名称
spring.shardingsphere.datasource.<actual-data-source-name>.type= # 数据库连接池全类名
spring.shardingsphere.datasource.<actual-data-source-name>.driver-class-name= # 数据库驱动类名,以数据库连接池自身配置为准
spring.shardingsphere.datasource.<actual-data-source-name>.jdbc-url= # 数据库 URL 连接,以数据库连接池自身配置为准
spring.shardingsphere.datasource.<actual-data-source-name>.username= # 数据库用户名,以数据库连接池自身配置为准
spring.shardingsphere.datasource.<actual-data-source-name>.password= # 数据库密码,以数据库连接池自身配置为准
spring.shardingsphere.datasource.<actual-data-source-name>.<xxx>= # ... 数据库连接池的其它属性

注意:当使用 ShardingSphere JDBC 时,JDBC 池的属性名取决于各自 JDBC 池自己的定义,并不由 ShardingSphere 硬定义,相关的处理可以参考类org.apache.shardingsphere.infra.datasource.pool.creator.DataSourcePoolCreator。例如对于 Alibaba Druid 1.2.9 而言,使用url代替如下示例中的jdbc-url是预期行为。

在这里插入图片描述

示例如下:

spring:
    shardingsphere:
        datasource:
          names: master,slave
          # 主数据源
          master:
            type: com.alibaba.druid.pool.DruidDataSource
            driver-class-name: com.mysql.cj.jdbc.Driver
            url: jdbc:mysql://192.168.60.100:3307/db1
            username: root
            password: "you_password"
          # 从数据源
          slave:
            type: com.alibaba.druid.pool.DruidDataSource
            driver-class-name: com.mysql.cj.jdbc.Driver
            url: jdbc:mysql://192.168.60.100:3308/db2
            username: root
            password: "you_password"
1.2.2 读写分离配置

这里我们配置静态读写分离

参考官方文档:读写分离 :: ShardingSphere (apache.org)

spring.shardingsphere.datasource.names= # 省略数据源配置,请参考使用手册

spring.shardingsphere.rules.readwrite-splitting.data-sources.<readwrite-splitting-data-source-name>.static-strategy.write-data-source-name= # 写库数据源名称
spring.shardingsphere.rules.readwrite-splitting.data-sources.<readwrite-splitting-data-source-name>.static-strategy.read-data-source-names= # 读库数据源列表,多个从数据源用逗号分隔
spring.shardingsphere.rules.readwrite-splitting.data-sources.<readwrite-splitting-data-source-name>.load-balancer-name= # 负载均衡算法名称

# 负载均衡算法配置
spring.shardingsphere.rules.readwrite-splitting.load-balancers.<load-balance-algorithm-name>.type= # 负载均衡算法类型
spring.shardingsphere.rules.readwrite-splitting.load-balancers.<load-balance-algorithm-name>.props.xxx= # 负载均衡算法属性配置

我的示例:

spring:
    shardingsphere:
        rules:
          readwrite-splitting:
            data-sources:
              read-write-datasource:
                static-strategy:
                  # 写库数据源名称
                  write-data-source-name: master
                  # 读库数据源列表,多个从数据源用逗号分隔
                  read-data-source-names: slave
                # 负载均衡算法名称
                load-balancer-name: round_robin
            # 负载均衡算法配置
            load-balancers:
              round_robin:
                # 负载均衡算法类型
                type: ROUND_ROBIN
                # 负载均衡算法属性配置
                # props:
1.2.3 便于调试的附加配置
spring:
    shardingsphere: 
        props:
          sql:
            show: true #开启SQL显示,默认false

其他配置,请参考官方文档

2. ShardingSphere 5.3.x

升级ShardingSphere 5.3.x后取消了Spring Boot StarterSpring Namespace 等配置,因此我们使用导入配置文件的方式。

其他参考官方文档:概览 :: ShardingSphere (apache.org)(注意选择文档版本)

2.1 引入当前最新依赖坐标

<dependency>
    <groupId>org.apache.shardingsphere</groupId>
    <artifactId>shardingsphere-jdbc-core</artifactId>
    <version>5.3.2</version>
</dependency>

如果使用的是springboot2.x同上,覆盖snakeyaml,原因相同。

<dependency>
    <groupId>org.yaml</groupId>
    <artifactId>snakeyaml</artifactId>
    <version>1.33</version>
</dependency>

2.2 导入相应的配置

参考官方文档,在springboot的配置文件加入相应配置信息:ShardingSphere-JDBC :: ShardingSphere (apache.org)

注意:datasource最好不再加其他配置,否则可能出现未知错误

# 配置 DataSource Driver
spring.datasource.driver-class-name=org.apache.shardingsphere.driver.ShardingSphereDriver
# 指定 YAML 配置文件
spring.datasource.url=jdbc:shardingsphere:classpath:xxx.yaml

我的配置,我配置文件命名为sharding-config.yaml

spring:
  datasource:
    driver-class-name: org.apache.shardingsphere.driver.ShardingSphereDriver
    url: jdbc:shardingsphere:classpath:sharding-config.yaml
2.2.1 数据源配置

同上,去掉druid的starter坐标,并且需要修改配置的一些项目

在这里插入图片描述

官方配置:

dataSources: # 数据源配置,可配置多个 <data-source-name>
  <data_source_name>: # 数据源名称
    dataSourceClassName: # 数据源完整类名
    driverClassName: # 数据库驱动类名,以数据库连接池自身配置为准
    jdbcUrl: # 数据库 URL 连接,以数据库连接池自身配置为准
    username: # 数据库用户名,以数据库连接池自身配置为准
    password: # 数据库密码,以数据库连接池自身配置为准
    # ... 数据库连接池的其它属性

我的配置:

dataSources:
  master:
    dataSourceClassName: com.alibaba.druid.pool.DruidDataSource
    driverClassName: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://192.168.60.100:3307/db1
    username: root
    password: "you_password"
    # ... 数据库连接池的其它属性
  slave:
    dataSourceClassName: com.alibaba.druid.pool.DruidDataSource
    driverClassName: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://192.168.60.100:3308/db2
    username: root
    password: "you_password"
    # ... 数据库连接池的其它属性
2.2.2 读写分离配置

这里我们配置静态读写分离

参考官方文档:读写分离 :: ShardingSphere (apache.org)

值得注意的是,官方文档有错误,在参数解释中,一些配置项使用了_分隔命名,但是会运行会显示解析错误,因此需要改为驼峰命名,官方文档的示例是正确的:

官方文档错误示例:

在这里插入图片描述

官方文档正确示例:

在这里插入图片描述

不知道为什么,官方文档有误,至少作者使用的5.3.2版本需要驼峰命名。

改正后的静态读写的官方示例:

rules:
- !READWRITE_SPLITTING
  dataSources:
    <data_source_name> (+): # 读写分离逻辑数据源名称
       staticStrategy: # 读写分离类型
         writeDataSourceName: # 写库数据源名称
         readDataSourceNames: # 读库数据源名称,多个从数据源用逗号分隔
       loadBalancerName: # 负载均衡算法名称
  
  # 负载均衡算法配置
  loadBalancers:
    <load_balancer_name> (+): # 负载均衡算法名称
      type: # 负载均衡算法类型
      props: # 负载均衡算法属性配置
        # ...

我的示例:

rules:
  - !READWRITE_SPLITTING
    dataSources:
      # 读写分离逻辑数据源名称
      readwrite_ds:
        # 读写分离类型
        staticStrategy:
          # 写库数据源名称
          writeDataSourceName: master
          # 读库数据源名称,多个从数据源用逗号分隔,或者使用数组表示
          readDataSourceNames:
            - slave
        # 负载均衡算法名称
        loadBalancerName: round_robin
    # 负载均衡算法配置
    loadBalancers:
      # 负载均衡算法名称
      round_robin:
        # 负载均衡算法类型
        type: ROUND_ROBIN
        # 负载均衡算法属性配置
        # props:
        # ...
2.2.3 便于调试的附加配置

同上

props:
  sql-show: true

更多配置请参考官方文档

3. 单机模式下修改数据源的问题

使用druid正确配置数据源并运行后,发现数据源hikariDataSource依旧被加载,因此会加载两个数据源:

在这里插入图片描述

在查询github相关问题后,发现了这个Issue:关于默认连接池的困惑问题 ·问题 #24348 ·Apache / Shardingsphere (github.com)

在这里插入图片描述

看起来,这个问题没有解决,应该对运行没有影响。

4. 错误汇总

4.1 新版在springboot2 中没有覆盖SnakeYAML

错误信息:

Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2023-05-18 10:54:14.320 ERROR 22560 --- [  restartedMain] o.s.b.d.LoggingFailureAnalysisReporter   : 

***************************
APPLICATION FAILED TO START
***************************

Description:

An attempt was made to call a method that does not exist. The attempt was made from the following location:

    org.apache.shardingsphere.infra.util.yaml.constructor.ShardingSphereYamlConstructor$1.<init>(ShardingSphereYamlConstructor.java:45)

The following method did not exist:
···

解决方案:覆盖SnakeYAML

<dependency>
    <groupId>org.yaml</groupId>
    <artifactId>snakeyaml</artifactId>
    <version>1.33</version>
</dependency>

方案来源:https://github.com/apache/shardingsphere/issues/21476

4.2 使用了druid的starter依赖

使用了druid的starter依赖,或者设置了spring.datasource.type为druid

错误信息:

2023-05-18 10:58:10.015 ERROR 29788 --- [  restartedMain] com.alibaba.druid.pool.DruidDataSource   : testWhileIdle is true, validationQuery not set

或者

···
2023-05-18 11:00:14.900 ERROR 24408 --- [reate-664989078] com.alibaba.druid.pool.DruidDataSource   : create connection RuntimeException

java.lang.NullPointerException: null
	at com.alibaba.druid.pool.DruidAbstractDataSource.createPhysicalConnection(DruidAbstractDataSource.java:1764) ~[druid-1.2.18.jar:na]
	at com.alibaba.druid.pool.DruidDataSource$CreateConnectionThread.run(DruidDataSource.java:2942) ~[druid-1.2.18.jar:na]
···

解决方案:禁用druidstarter坐标,去掉spring.datasource.type内容

<!-- 禁用druid的starter依赖 -->
<!--<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid-spring-boot-starter</artifactId>
    <version>1.2.16</version>
</dependency>-->
<!-- 使用ShardingSphere读写分离不能使用druid的starter -->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid</artifactId>
    <version>1.2.18</version>
</dependency>

方案来源:https://github.com/apache/shardingsphere/wiki/FAQ#jdbc

4.3 配置信息错误1 数据源相关配置错误

druid的数据源配置项,例如HikariDataSourcejdbcUrl,而druidurl,请仔细参考官方文档信息。

错误信息:

2023-05-18 11:03:52.326 ERROR 25756 --- [  restartedMain] com.alibaba.druid.pool.DruidDataSource   : {dataSource-1} init error

java.sql.SQLException: url not set
	at com.alibaba.druid.pool.DruidDataSource.resolveDriver(DruidDataSource.java:1274) ~[druid-1.2.18.jar:na]
	at com.alibaba.druid.pool.DruidDataSource.init(DruidDataSource.java:899) ~[druid-1.2.18.jar:na]
	at com.alibaba.druid.pool.DruidDataSource.getConnection(DruidDataSource.java:1463) ~[druid-1.2.18.jar:na]
	at com.alibaba.druid.pool.DruidDataSource.getConnection(DruidDataSource.java:1459) ~[druid-1.2.18.jar:na]
	at com.alibaba.druid.pool.DruidDataSource.getConnection(DruidDataSource.java:83) ~[druid-1.2.18.jar:na]
	at org.apache.shardingsphere.infra.datasource.state.DataSourceStateManager.checkState(DataSourceStateManager.java:84) ~[shardingsphere-infra-common-5.3.2.jar:5.3.2]
	at org.apache.shardingsphere.infra.datasource.state.DataSourceStateManager.initState(DataSourceStateManager.java:79) ~[shardingsphere-infra-common-5.3.2.jar:5.3.2]
···

解决方案:仔细检查配置信息

在这里插入图片描述

方案来源:数据源配置 :: ShardingSphere (apache.org)

4.4 配置信息错误2 配置文件配置项错误

可能1:参考官方文档过程中,目前文档中有配置项是下划线分隔,官方文档错误导致的问题

可能2:读者不仔细参考相关文档,导致yaml顺序层次错误

可能3:读者参考的官方文档与使用的版本不匹配导致的配置项错误

错误信息:

2023-05-18 11:11:50.063 ERROR 16664 --- [  restartedMain] com.zaxxer.hikari.pool.HikariPool        : HikariPool-1 - Exception during pool initialization.

org.yaml.snakeyaml.constructor.ConstructorException: Cannot create property=rules for JavaBean=org.apache.shardingsphere.infra.yaml.config.pojo.YamlRootConfiguration@74525630
 in 'reader', line 1, column 1:
    dataSources:
    ^
Cannot create property=dataSources for JavaBean=org.apache.shardingsphere.readwritesplitting.yaml.config.YamlReadwriteSplittingRuleConfiguration@a85bdef
 in 'reader', line 17, column 5:
      - !READWRITE_SPLITTING
        ^
Cannot create property=static_strategy for JavaBean=org.apache.shardingsphere.readwritesplitting.yaml.config.rule.YamlReadwriteSplittingDataSourceRuleConfiguration@1b2181f6
 in 'reader', line 22, column 9:
            static_strategy:
            ^
Unable to find property 'static_strategy' on class: org.apache.shardingsphere.readwritesplitting.yaml.config.rule.YamlReadwriteSplittingDataSourceRuleConfiguration
 in 'reader', line 24, column 11:
              writeDataSourceName: master
              ^

 in 'reader', line 20, column 7:
          readwrite_ds:
          ^

 in 'reader', line 17, column 3:
      - !READWRITE_SPLITTING
      ^

	at org.yaml.snakeyaml.constructor.Constructor$ConstructMapping.constructJavaBean2ndStep(Constructor.java:321) ~[snakeyaml-1.33.jar:na]
	at org.yaml.snakeyaml.constructor.Constructor$ConstructMapping.construct(Constructor.java:207) ~[snakeyaml-1.33.jar:na]
	at org.yaml.snakeyaml.constructor.Constructor$ConstructYamlObject.construct(Constructor.java:358) ~[snakeyaml-1.33.jar:na]
	at org.yaml.snakeyaml.constructor.BaseConstructor.constructObjectNoCheck(BaseConstructor.java:270) ~[snakeyaml-1.33.jar:na]
	at org.yaml.snakeyaml.constructor.BaseConstructor.constructObject(BaseConstructor.java:253) ~[snakeyaml-1.33.jar:na]
	at org.yaml.snakeyaml.constructor.BaseConstructor.constructDocument(BaseConstructor.java:207) ~[snakeyaml-1.33.jar:na]
	at org.yaml.snakeyaml.constructor.BaseConstructor.getSingleData(BaseConstructor.java:191) ~[snakeyaml-1.33.jar:na]
···

解决方案:仔细检查,配置项信息,查看官方文档或者github的Issues寻找正确的配置信息,注意使用的版本;当前,截至文章发出前(2023.5.18)最新版的参考文档的读写分离配置项有错误,下划线分隔需要改为驼峰命名,详细内容见上面配置相关内容。

方案来源:https://github.com/apache/shardingsphere/issues/25191

5. 读写分离文章的所有参考内容

  1. Apache ShardingSphere

  2. apache/shardingsphere: Ecosystem to transform any database into a distributed database system, and enhance it with sharding, elastic scaling, encryption features & more (github.com)

  3. ShardingSphere 5.3 系列Spring 配置升级指南

  • 9
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值