zoukankan      html  css  js  c++  java
  • Sharding-JDBC实现读写分离

    参考资料:猿天地  https://mp.weixin.qq.com/s/kp2lJHpTMz4bDWkJYjVbOQ  作者:尹吉欢  

    技术选型:SpringBoot + Sharding-JDBC + MyBatis

    使用Sharding-JDBC配置读写分离,优点在于数据源完全有Sharding托管,写操作自动执行master库,读操作自动执行slave库。不需要程序员在程序中关注这个实现了。

    1. 核心jar包

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.6.RELEASE</version>
    </parent>
    <dependencies>
        <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>
        <!-- sharding -->
        <dependency>
            <groupId>org.apache.shardingsphere</groupId>
            <artifactId>sharding-jdbc-spring-boot-starter</artifactId>
            <version>4.0.0-RC1</version>
        </dependency>
        <!-- mybatis-plus -->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.2.0</version>
        </dependency>
        <!--阿里数据库连接池 -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.1.14</version>
        </dependency>
        <!-- mysql -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.18</version>
         </dependency>
         <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.60</version>
         </dependency>
     </dependencies>

    2. yml文件配置

    spring:
      main:
        allow-bean-definition-overriding: true
      shardingsphere:
        datasource:
          names:
            master,slave
          # 主数据源
          master:
            type: com.alibaba.druid.pool.DruidDataSource
            driver-class-name: com.mysql.cj.jdbc.Driver
            url: jdbc:mysql://localhost:3306/db_master?characterEncoding=utf-8
            username: ****
            password: ****
          # 从数据源
          slave:
            type: com.alibaba.druid.pool.DruidDataSource
            driver-class-name: com.mysql.cj.jdbc.Driver
            url: jdbc:mysql://localhost:3306/db_slave?characterEncoding=utf-8
            username: ****
            password: ****
        masterslave:
          # 读写分离配置
          load-balance-algorithm-type: round_robin
          # 最终的数据源名称
          name: dataSource
          # 主库数据源名称
          master-data-source-name: master
          # 从库数据源名称列表,多个逗号分隔
          slave-data-source-names: slave
        props:
          # 开启SQL显示,默认false
          sql:
            show: true

    参数解读:

    load-balance-algorithm-type 用于配置从库负载均衡算法类型,可选值:ROUND_ROBIN(轮询),RANDOM(随机)

    props.sql.show=true 在执行SQL时,会打印SQL,并显示执行库的名称

    3. 项目启动测试

    看到下面日志就说明配置成功了

    2019-12-17 16:12:16.004  INFO 19164 --- [   main] com.alibaba.druid.pool.DruidDataSource   : {dataSource-1} inited
    2019-12-17 16:12:17.458  INFO 19164 --- [   main] com.alibaba.druid.pool.DruidDataSource   : {dataSource-2} inited

    执行SQL时,会打印一下日志:

    [ main] ShardingSphere-SQL : Rule Type: master-slave
    [ main] ShardingSphere-SQL : SQL: SELECT  id,address,gender,username  FROM user_info ::: DataSources: slave

    4. 相关问题

      读写分离架构中经常出现,那就是读延迟的问题如何解决?

      刚插入一条数据,然后马上就要去读取,这个时候有可能会读取不到?归根到底是因为主节点写入完之后数据是要复制给从节点的,读不到的原因是复制的时间比较长,也就是说数据还没复制到从节点,你就已经去从节点读取了,肯定读不到。mysql5.7 的主从复制是多线程了,意味着速度会变快,但是不一定能保证百分百马上读取到,这个问题我们可以有两种方式解决:

      (1)业务层面妥协,是否操作完之后马上要进行读取

      (2)对于操作完马上要读出来的,且业务上不能妥协的,我们可以对于这类的读取直接走主库,当然Sharding-JDBC也是考虑到这个问题的存在,所以给我们提供了一个功能,可以让用户在使用的时候指定要不要走主库进行读取。在读取前使用下面的方式进行设置就可以了:

        public List<UserInfo> getList() {
            // 强制路由主库
            HintManager.getInstance().setMasterRouteOnly();
            return this.list();
        }
  • 相关阅读:
    可空类型转换为不可空的普通类型
    如何使用AspNetPager分页控件和ObjectDataSource控件进行分页
    TFS映射后丢失引用的问题
    (很好用)JS时间控件实现日期的多选
    取两个日期之间的非工作日的天数(指的是周六、周日)
    在日期格式化的时候提示错误:Tostring没有采用一个参数的重载
    Linq返回的集合类型不是已有的表格类型时的写法(谨记:列表的时候用)
    系统缓存全解析6:数据库缓存依赖
    实现文本框动态限制字数的实现(好方法)
    实现GridView内容循环滚动
  • 原文地址:https://www.cnblogs.com/huanshilang/p/12055296.html
Copyright © 2011-2022 走看看