SpringBoot整合ShardingSphere-JDBC 5.3.2 实现读写分离、分库分表。

👩🏽‍💻个人主页:阿木木AEcru

🔥 系列专栏:《Docker容器化部署系列》 《Java每日面筋》

💹每一次技术突破,都是对自我能力的挑战和超越。

Docker部署MYSQL主从详细教程-阿木木AEcru-CSDN

那天写了 部署mysql主从后,想了想,还是有必要出多一篇关于ShardingSphere-JDBC 读写分离、分库分表的文章,做就得做全套,那么今天就来实现一下。

目录

    • 一、前言
      • 1.1 读写分离是什么?
      • 1.2 分库分表是什么?
    • 二、ShardingSphere-JDBC 实现 读写分离
      • 2.1 读写分离逻辑
      • 2.2 实现读写分离
      • 2.3 pom文件
      • 2.4 application.yml 配置文件
      • 2.5 (重点)sharding-jdbc.yml 配置文件
      • 2.6 Controller测试接口
      • 2.7 请求测试结果
    • 三、ShardingSphere-Jdbc 实现 数据分片(分库分表)
      • 3.1 (重点)sharding-jdbc.yml 配置文件
      • 3.2 Controller 测试接口
      • 3.3 写操作请求测试结果
      • 3.4 读操作请求测试结果
    • 四、结尾

一、前言

首先我们得知道读写分离以及分库分表的基本概念。

1.1 读写分离是什么?

读写分离其核心思想是将数据库的读操作(查询)和写操作(插入、更新、删除)分离到不同的数据库服务器上。这样做是为了提高数据库系统的处理能力和伸缩性,同时减轻单个数据库服务器的负载。

这就是为什么需要主库和从库的原因了,大部分的写操作都是在 主库进行操作的,而从库则承担了读操作,如果说需要更加的高可用的话,可以部署多出多从的架构。将读写操作分担导了不同的节点,更有利于服务的稳定性。不会说某一台的负载特别高。

1.2 分库分表是什么?

分库就是根据根据业务耦合性将一个库中的多张表拆分出来独立到另外一个库。例如在微服务结构中就需要分库,因为一个服务就需要一个库,而分库的粒度也是取决于你服务的粒度。

分表有两种分表的方式,垂直分表以及水平分表。

垂直分表:是将一个表中的一部分字段抽离出来做一个冗余的表,当一个表的字段非常多,且某些字段的访问频率较低或字段较大时,这时就非常适合使用垂直分表,将访问频率大的字段、或者较大(存储字符较多) 的字段抽离出来独立一张表。这样单张表的数据量就不会太大,从而提高查询效率

水平分表:当单表行数非常大,导致查询和更新操作变慢时,这时就适合使用水平分表, 将表的数据按照某种规则(如用户ID、时间等)分散到多个表中,每个表包含完整的表结构,但是数据是分散的。 这样单张表的行数就不会太大,一般单张表建议是在500w行左右。

总的来说,其实分表就是为了使得单张表的数据量不会过大而影响查询效率,当然最佳优化肯定还是需要优化查询SQL以及索引等方式来进行调优。

好了,了解了什么是读写分离以及分库分表后,就进入了今天的主题了,我们接着往下看。

二、ShardingSphere-JDBC 实现 读写分离

ShardingSphere-JDBC 定位为轻量级 Java 框架,在 Java 的 JDBC 层提供的额外服务。ShardingSphere官网

2.1 读写分离逻辑

读写分离则是根据 SQL 语义的分析,将读操作和写操作分别路由至主库与从库。需要注意的是,shardingSphere 不会帮你实现数据库的主从同步,这个就需要你自己去配置数据库了,文章开头也有mysql配置主从的教程链接,感兴趣的小伙伴可以去看看。

与ShardingSphere-proxy对比

这里简单讲讲ShardingSphere-proxy,它实际上是再请求到实际的数据库之前做了一层代理,请求先到了ShardingSphere-proxy 上,然后通过一系列的算法将sql分散在不同的数据库节点。这样的好处也就是不用每个服务都独立配置,只需要配置这一层代理就行了。坏处就是需要独立占用服务器的资源,处理请求的瓶颈也会转移到它这里。 这就有点像 Mycat了,感兴趣的小伙伴可以去了解一下。

2.2 实现读写分离

下面我将会通过一个demo来演示。主要代码我会在后面的贴出来。需要源码的可以私信博主。

这是demo的项目结构。

2.3 pom文件

<dependencies>
        <!--SpringBoot相关依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        <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>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <!--Shardingjdbc-->
        <dependency>
            <groupId>org.apache.shardingsphere</groupId>
            <artifactId>shardingsphere-jdbc-core</artifactId>
            <version>5.3.2</version>
        </dependency>
        <!--连接池-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.2.9</version>
        </dependency>

        <!--mysql 驱动-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.47</version>
        </dependency>
        <!--mybatis-->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.5.3.1</version>
        </dependency>
        <!--mybatis plus extension,包含了mybatis plus core-->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-extension</artifactId>
            <version>3.5.3.1</version>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <!-- hutool工具类-->
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-crypto</artifactId>
            <version>5.8.10</version>
        </dependency>

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

2.4 application.yml 配置文件

# 服务配置
server:
  # 应用程序运行的端口
  port: 9001
  # Servlet的上下文路径
  servlet:
    context-path: /sharding-jdbc

# 日志配置
logging:
  # 设置特定包(通常是应用程序包)的日志级别
  level:
    # 设置com.example.demo包下的类的日志级别为debug
    com.example.demo: debug
    # 设置com.example.demo.repository包下的类的日志级别为trace(更详细)
    com.example.demo.repository: trace

# Spring框架配置
spring:
  # 数据源配置
  datasource:
    # 驱动类名,这里使用的是ShardingSphere提供的驱动
    driver-class-name: org.apache.shardingsphere.driver.ShardingSphereDriver
    # 数据源URL,使用ShardingSphere的JDBC URL格式
    url: jdbc:shardingsphere:classpath:sharding-jdbc.yml
    # 这里指定了ShardingSphere的配置文件位置,该文件包含了分片规则等配置

  # JPA(Java Persistence API)配置
  jpa:
    # 是否显示执行的SQL语句
    show-sql: true
    # JPA属性配置
    properties:
      # Hibernate的配置属性
      hibernate:
        # 自动更新数据库表结构
        ddl.auto: update
        # 打印执行时间统计信息
        generate_statistics: true
      # 指定数据库方言,这里使用的是MySQL 5的InnoDB方言
      database-platform: org.hibernate.dialect.MySQL5InnoDBDialect
    # 是否在视图(View)中打开查询
    open-in-view: false

2.5 (重点)sharding-jdbc.yml 配置文件


# 数据源配置
dataSources:
  # 主数据库配置
  master1:
    # 数据源类名,这里使用的是阿里巴巴的Druid连接池
    dataSourceClassName: com.alibaba.druid.pool.DruidDataSource
    # JDBC驱动类名
    driverClassName: com.mysql.cj.jdbc.Driver
    # 数据库连接URL,包括数据库地址、端口、数据库名以及连接参数
    url: jdbc:mysql://121.36.95.63:3306/test?useUnicode=true&characterEncoding=UTF-8&useSSL=false&allowPublicKeyRetrieval=true&allowMultiQueries=true&autoReconnect=true&serverTimezone=GMT%2B8
    # 数据库登录用户名
    username: root
    # 数据库登录密码
    password: root
  # 从数据库1配置
  slave1:
    # 数据源类名,与主数据库相同
    dataSourceClassName: com.alibaba.druid.pool.DruidDataSource
    # JDBC驱动类名,与主数据库相同
    driverClassName: com.mysql.cj.jdbc.Driver
    # 数据库连接URL,与主数据库类似,但端口不同
    url: jdbc:mysql://121.36.95.63:3307/test?useUnicode=true&characterEncoding=UTF-8&useSSL=false&allowPublicKeyRetrieval=true&allowMultiQueries=true&autoReconnect=true&serverTimezone=GMT%2B8
    # 数据库登录用户名,与主数据库相同
    username: root
    # 数据库登录密码,与主数据库相同
    password: root

# 规则配置
rules:
  # 声明使用读写分离规则
  - !READWRITE_SPLITTING
    # 读写分离的数据源配置
    dataSources:
      readwrite_ds:
        # 静态策略配置
        staticStrategy:
          # 写操作指向的主数据源名称
          writeDataSourceName: master1
          # 读操作指向的从数据源名称列表
          readDataSourceNames:
            - slave1
        # 负载均衡器名称
      loadBalancerName: round_robin
    # 负载均衡器配置
    loadBalancers:
      # 轮询负载均衡器
      round_robin:
        # 负载均衡器类型为轮询
        type: ROUND_ROBIN

# 属性配置
props:
  # 是否显示执行的SQL语句
  sql-show: true

2.6 Controller测试接口

其他代码我这边就不贴了,重点是上面配置文件,如果有 需要源码的小伙伴,可以私信我。

@RestController
@RequestMapping("/user")
@RequiredArgsConstructor
public class UserController {

    private final UserService userService;

    @GetMapping("/list")
    public R getList(){
        return R.ok(userService.list());
    }

    @PostMapping("/save")
    public R save(){
        User user = new User();
        user.setName("小明"+String.format("%06d",RandomUtils.nextInt(0,1000000)));
        user.setAddress("广州");
        user.setAge(RandomUtils.nextInt(18,100));
        user.setCreateTime(LocalDateTime.now());
        user.setUpdateTime(LocalDateTime.now());
        return R.ok(userService.save(user));
    }
}

2.7 请求测试结果

调用查询接口

调用写入接口

三、ShardingSphere-Jdbc 实现 数据分片(分库分表)

3.1 (重点)sharding-jdbc.yml 配置文件

# 数据源配置
dataSources:
  # 主数据库配置
  master1:
    # 数据源类名,这里使用的是阿里巴巴的Druid连接池
    dataSourceClassName: com.alibaba.druid.pool.DruidDataSource
    # JDBC驱动类名
    driverClassName: com.mysql.cj.jdbc.Driver
    # 数据库连接URL,包括数据库地址、端口、数据库名以及连接参数
    url: jdbc:mysql://121.36.95.63:3306/test?useUnicode=true&characterEncoding=UTF-8&useSSL=false&allowPublicKeyRetrieval=true&allowMultiQueries=true&autoReconnect=true&serverTimezone=GMT%2B8
    # 数据库登录用户名
    username: root
    # 数据库登录密码
    password: root

# 分片规则配置
rules:
  # 读写分离配置
  - !READWRITE_SPLITTING
    # 定义读写分离的数据源
    dataSources:
      readwrite_ds:
        # 静态策略,定义写操作指向的数据源和读操作指向的数据源列表
        staticStrategy:
          writeDataSourceName: master1  # 写操作指向的主数据源名称
          readDataSourceNames:  # 读操作指向的从数据源名称列表
            - slave1
        # 负载均衡器名称
      loadBalancerName: round_robin
    # 定义负载均衡器的类型和策略
    loadBalancers:
      round_robin:
        type: ROUND_ROBIN  # 轮询负载均衡策略

  # 分表路由配置
  - !SHARDING
    # 定义需要分片的表及其分片策略
    tables:
      sys_log:
        # 定义实际的数据节点,包括数据源名称和表名
        actualDataNodes: master1.sys_log_$->{0..2}
        # 定义表的分片策略
        tableStrategy:
          standard:
            # 分片键和分片算法名称
            shardingColumn: id
            shardingAlgorithmName: t-log-inline
        # 定义键生成策略
        keyGenerateStrategy:
          column: id  # 指定键生成策略的列名
          keyGeneratorName: snowflake  # 指定使用的键生成器名称 这里使用的雪花算法


    # 定义分片算法
    shardingAlgorithms:
      t-log-inline:
        # 分片算法类型
        type: INLINE
        # 分片算法的属性配置
        props:
          algorithm-expression: sys_log_$->{id % 3}  # 分片算法表达式,根据id字段的值进行取模运算

    # 定义键生成器
    keyGenerators:
      snowflake:
        # 键生成器类型
        type: SNOWFLAKE

# 其他属性配置
props:
  sql-show: true  # 是否显示执行的SQL语句,便于调试

3.2 Controller 测试接口

3.3 写操作请求测试结果

这里通过 id 字段进行取模,有几张表就取模多少就行。这里使用的是最基础的分表策略,ShardingSphere-Jdbc 还支持 数据库分片,通过不同的规则计算 来进行 不同数据库的读写操作, 因为我这里 实现了读写分离,就不好做 数据库分片了, 不然数据库的数据会不一致。 感兴趣的小伙伴可以一起再评论区交流一下。 ShardingSphere-Jdbc 也还支持 各种分表策略,也可以自定义分表策略,常见的有,按照时间范围(年月日) , 按照 数据 哈希运算取模 、按照 业务字段 等。

3.4 读操作请求测试结果

这里由于没有用id字段查询,所以没有路由到对应的表来查,就会所有表都查询然后汇总结果。

当指定了id(分表路由字段)作为条件之后,就可以精准的路由到某张表查询,这样查询效率就会快很多。

四、结尾

感谢您的观看! 如果本文对您有帮助,麻烦用您发财的小手点个三连吧!您的支持就是作者前进的最大动力!再次感谢!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/481630.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

计算机网络:物理层下的传输媒体概览

✨✨ 欢迎大家来访Srlua的博文&#xff08;づ&#xffe3;3&#xffe3;&#xff09;づ╭❤&#xff5e;✨✨ &#x1f31f;&#x1f31f; 欢迎各位亲爱的读者&#xff0c;感谢你们抽出宝贵的时间来阅读我的文章。 我是Srlua小谢&#xff0c;在这里我会分享我的知识和经验。&am…

秘钥缩写、全称和中文名

三级加密体系 第一级&#xff1a; LMK(LOCAL MAIN KEY)&#xff0c;存放于HSM机中&#xff0c;用于对所有存于本地的其他密钥和加密数据进行加密&#xff0c;是最重要的密钥。 第二级&#xff1a; 如ZMK&#xff08;即平时大家说的主密钥MK&#xff09;&#xff0c;存于本地或…

autorun 病毒清除工具 源码

** autorun 病毒清除工具 源码 ** 1、新建一个记事本&#xff1a;AutoRun病毒清理工具.txt&#xff0c;复制以下代码&#xff1a; Autorun 病毒清除工具 Echo Offcolor 2etitle Autorun 病毒清除工具-By 段子手168 2023-10-25Rem 杀进程taskkill /F /IM SocksA.exe /IM …

hyper-v虚拟机使用宿主机usb设备

文章目录 一、修改宿主机组策略二、使用 一、修改宿主机组策略 在宿主电脑上&#xff0c;按 winr 组合键打开运行窗口&#xff0c;输入 gpedit.msc 打开组策略编辑器&#xff0c;依次点击计算机配置- 管理模板- Windows 组件- 远程桌面服务- 远程桌面会话客户端- RemoteFX USB…

目标检测——PP-YOLOE算法解读

PP-YOLO系列&#xff0c;均是基于百度自研PaddlePaddle深度学习框架发布的算法&#xff0c;2020年基于YOLOv3改进发布PP-YOLO&#xff0c;2021年发布PP-YOLOv2和移动端检测算法PP-PicoDet&#xff0c;2022年发布PP-YOLOE和PP-YOLOE-R。由于均是一个系列&#xff0c;所以放一起解…

一键入门Ubuntu22!

目录 一、安装 二、常用目录 三、常用指令 四、用户指令 五、ssh与scp 六、服务相关 七、Python与Pycharm 八、Vim编辑器 九、Ubuntu22下使用Mysql 十、Ubuntu22下使用mongodb 十一、Ubuntu22下使用redis Ubuntu是一个基于Debian的开源操作系统&#xff0c;由Canoni…

基于霍夫检测(hough变换)的人眼瞳孔定位,Matlab实现

博主简介&#xff1a; 专注、专一于Matlab图像处理学习、交流&#xff0c;matlab图像代码代做/项目合作可以联系&#xff08;QQ:3249726188&#xff09; 个人主页&#xff1a;Matlab_ImagePro-CSDN博客 原则&#xff1a;代码均由本人编写完成&#xff0c;非中介&#xff0c;提供…

网络原理(4)——TCP协议的特性

目录 一、滑动窗口 1、ack丢了 2、数据丢了 二、流量控制&#xff08;流控&#xff09; 三、拥塞控制 拥塞窗口动态变化的规则 四、延时应答 五、捎带应答 六、面向字节流 七、异常情况 &#xff08;1&#xff09;进程崩溃了 &#xff08;2&#xff09;其中一方关机…

虚拟机开机启动失败,进入(initramfs)解决办法

虚拟机开机启动失败&#xff0c;进入&#xff08;initramfs&#xff09;解决办法 打开虚拟机中Ubuntu时进入(initramfs)&#xff0c;导致无法进入桌面。问题如下图显示&#xff1a; 命令行输入 fsck -y /dev/sda5输入 exit进入 选择root 后回车 输入虚拟机的密码 进入 root …

网络原理(5)——IP协议(网络层)

目录 一、IP协议报头介绍 1、4位版本 2、4位首部长度 3、8位服务器类型 4、16位总长度 5、16位标识位 6、3位标志位 7、13位偏移量 8、8位生存空间 9、8位协议 10、16位首部检验和 11、32位源IP地址 12、32位目的IP地址 二、IP协议如何管理地址&#xff1f; 1、动…

《剑指 Offer》专项突破版 - 面试题 88 : 动态规划的基础知识(C++ 实现)

目录 前言 面试题 88 : 爬楼梯的最少成本 一、分析确定状态转移方程 二、递归代码 三、使用缓存的递归代码 四、空间复杂度为 O(n) 的迭代代码 五、空间复杂度为 O(1) 的迭代代码 前言 动态规划是目前算法面试中的热门话题&#xff0c;应聘者经常在各大公司的面试中遇到…

STM32 CAN的工作模式

STM32 CAN的工作模式 正常模式 正常模式下就是一个正常的CAN节点&#xff0c;可以向总线发送数据和接收数据。 静默模式 静默模式下&#xff0c;它自己的输出端的逻辑0数据会直接传输到它自己的输入端&#xff0c;逻辑1可以被发送到总线&#xff0c;所以它不能向总线发送显性…

STM32利用串口标准库发送字节,发送数组,发送字符串,发送数字,实现printf功能。

早晨到现在刚刚完成的功能&#xff1a;发送字节&#xff0c;发送数组&#xff0c;发送字符串&#xff0c;发送数字&#xff0c;实现printf功能。 当然这是建立在昨天学习使用串口发送数据的基础上&#xff0c;新建立的功能函数&#xff0c;咱们先来看看这次实验的结果吧&#…

CCDP.02.OS正确部署后的Dashboard摘图说明

前言 在部署成功OpenStack后&#xff0c;应该可以在浏览器打开Dashboard&#xff0c;并对计算资源&#xff08;这里主要是指VM&#xff09;进行管理&#xff0c;也可以在Dashboard上面查看OpenStack是否存在错误&#xff0c;下面&#xff0c;已针对检查的关键点&#xff0c;用红…

程序员表白

啥&#xff1f;&#xff01;你说程序员老实&#xff0c;认真工作&#xff0c;根本不会什么表白&#xff01;那你就错了&#xff01;(除了我) 那今天我们就来讲一下这几个代码&#xff01;赶紧复制下来&#xff0c;这些代码肯定有你有用的时候&#xff01; 1.Python爱心代码 im…

IAB欧洲发布首张泛欧洲数字零售媒体能力矩阵图

2024年1月18日&#xff0c;互动广告署-欧洲办事处&#xff08;IAB Europe)发布了首张泛欧洲数字零售媒体能力矩阵图。为媒体买家提供的新资源概述了在欧洲运营的零售商提供的现场、场外和数字店内零售媒体广告机会。 2024年1月18日&#xff0c;比利时布鲁塞尔&#xff0c;欧洲领…

算法系列--递归(2)

&#x1f495;"什么样的灵魂就要什么样的养料&#xff0c;越悲怆的时候我越想嬉皮。"&#x1f495; 作者&#xff1a;Mylvzi 文章主要内容&#xff1a;算法系列–递归(2) 前言:今天带来的是算法系列--递归(2)的讲解,包含六个和二叉树相关的题目哦 1.计算布尔⼆叉树的…

企业微信可以更换公司主体吗?

企业微信变更主体有什么作用&#xff1f;当我们的企业因为各种原因需要注销或已经注销&#xff0c;或者运营变更等情况&#xff0c;企业微信无法继续使用原主体继续使用时&#xff0c;可以申请企业主体变更&#xff0c;变更为新的主体。企业微信变更主体的条件有哪些&#xff1…

Ambari+Metrics+Bigtop 全家桶编译部署攻略——Ambari系列

您的支持是我继续创作与分享的动力源泉!!! 您的支持是我继续创作与分享的动力源泉!!! 您的支持是我继续创作与分享的动力源泉!!! 写在前面: 1、源码已经完成Ambari+Metrics+Bigtop 最新版的编译及部署,后续会放魔改包和一件部署脚本 2、时间有限,我会尽快更新完毕所有内容…