SpringBoot集成Sharding——JDBC分库分表

Sharding——JDBC

它定位为轻量级Java框架,在Java的JDBC层提供的额外服务。它使用客户端直连数据库,以jar包形式提供服务,无需额外部署和依赖,可理解为增强版的JDBC驱动,完全兼容JDBC和各种ORM框架。

对比图:
SpringBoot集成Sharding——JDBC分库分表
开发人员只需正常写查询、mapper即可、无感知。

分库分表概念

随着业务的不断增长,数据也飞速增长,访问也随之变慢,添加从库、新建索引等很多操作仍严重下降,分库分表需求迫在眉睫。

方案一:
通过提升服务性能来提升数据处理能力,例如:扩容、CPU等,但成本很高。

方案二:
把数据分散在不同数据集中,大表拆成小表、数据落盘到不同库中,从而使得数据集变小从而提升性能。

  • 垂直分库
    为依据,按照业务需求将拆到不同库中。
    每个的结构不一样。
    每个的数据不一样,没有交集。
    所有库的并集是全量数据。

场景:
这一步拆分基本是服务化,例如,中间表、字典表、配置表等越来越多,可以将这些表拆分到单独库中,甚至可以微服务化。

  • 垂直分表
    字段为依据,按照字段活跃性拆到不同中。
    每张表结构不一样。
    每张表数据也不一样,至少有一列交集用于关联。
    所有表并集数据是全量数据。

场景:
用户表中有id、名称、住址等信息,每次查询用户信息时住址字段使次数很低,大字段等单独拆分一张,从而减少IO提升性能。

  • 水平分库
    字段为依据,按照一定策略(hash、range等),将一个中的数据拆分到多个库中。
    每个库结构都一样。
    每个库数据都不一样,没有交集。
    所有库并集是全量数据。

场景:
库多了,IO和CPU压力可以成倍缓解。

  • 水平分表
    字段为依据,按照一定策略(hash、range等),将一个中的数据拆分到多个表中。
    每张表结构都一样。
    每张表数据都不一样,没有交集。
    所有表并集是全量数据。

场景:
表的数据量少了,SQL执行效率高,IO和CPU压力可以成倍缓解。

POM文件

	<dependencies>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.3.2</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-actuator</artifactId>
        </dependency>

        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-generator</artifactId>
            <version>3.3.2</version>
        </dependency>

        <!-- Druid连接池 -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.1.10</version>
        </dependency>

        <!-- 分库分表 -->
        <dependency>
            <groupId>org.apache.shardingsphere</groupId>
            <artifactId>sharding-jdbc-spring-boot-starter</artifactId>
            <version>4.0.0-RC1</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
    </dependencies>

分表配置

新建数据库名:sharding
新建表名:tbl_dept_1和tbl_dept_2
表结构:

SpringBoot集成Sharding——JDBC分库分表

说明:根据dept_id进行分表选择。

yml文件:

spring:
  main:
    allow-bean-definition-overriding: true
  # 配置Sharding-JDBC的分片策略
  shardingsphere:
    # 配置数据源,给数据源起名g1,g2...此处可配置多数据源
    datasource:
      names: g1
      g1:
        type: "com.alibaba.druid.pool.DruidDataSource"
        driver-class-name: "com.mysql.cj.jdbc.Driver"
        url: "jdbc:mysql://localhost:3306/sharding?useLegacyDatetimeCode=false&serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull"
        username: "账号"
        password: "密码"
    # 配置表的分布,表的策略
    sharding:
      tables:
        # 表名
        tbl_dept: 
          actual-data-nodes: g1.tbl_dept_${0..1}
          key-generator:
            # 指定tbl_dept表 主键dept_id 生成策略为 SNOWFLAKE
            column: dept_id
            type: SNOWFLAKE
          table-strategy:
            inline:
              # 指定分片策略 约定dept_id值是偶数添加到tbl_dept_1表,如果dept_id奇数添加到tbl_dept_2表
              sharding-column: dept_id
              algorithm-expression: tbl_dept_${dept_id % 2 + 1}
    # 打开sql输出日志 
    props:
      sql:
        show: true

执行查询或插入代码:

TblDept byId = tblDeptService.getById(6);

执行效果日志:
SpringBoot集成Sharding——JDBC分库分表

分库配置

新建数据库名:sharding_1,sharding_2
在两个库中分别新建表名:tbl_dept_1和tbl_dept_2
表结构:

SpringBoot集成Sharding——JDBC分库分表

说明:根据s_id进行分库选择,根据dept_id进行分表选择。

yml文件:

spring:
  main:
    allow-bean-definition-overriding: true
  # 配置Sharding-JDBC的分片策略
  shardingsphere:
    # 配置数据源,给数据源起名g1,g2...此处可配置多数据源
    datasource:
      names: g1,g2
      g1:
        type: "com.alibaba.druid.pool.DruidDataSource"
        driver-class-name: "com.mysql.cj.jdbc.Driver"
        url: "jdbc:mysql://localhost:3306/sharding_1?useLegacyDatetimeCode=false&serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull"
        username: "账号"
        password: "密码"
      g2:
        type: "com.alibaba.druid.pool.DruidDataSource"
        driver-class-name: "com.mysql.cj.jdbc.Driver"
        url: "jdbc:mysql://localhost:3306/sharding_2?useLegacyDatetimeCode=false&serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull"
        username: "账号"
        password: "密码"
    # 配置表的分布,表的策略
    sharding:
      tables:
        # 表名
        tbl_dept:
          actual-data-nodes: g${1..2}.tbl_dept_${1..2}
          # 指定tbl_dept表 主键dept_id 生成策略为 SNOWFLAKE
          key-generator:
            column: dept_id
            type: SNOWFLAKE
          # 指定分片策略 约定dept_id值是偶数添加到tbl_dept_1表,如果dept_id奇数添加到tbl_dept_2表
          database-strategy:
            inline:
              sharding-column: s_id
              algorithm-expression: g${s_id % 2 + 1}
          table-strategy:
            inline:
              sharding-column: dept_id
              algorithm-expression: tbl_dept_${dept_id % 2 + 1}

    # 打开sql输出日志
    props:
      sql:
        show: true

执行查询或插入代码:

	TblDept tblDept = new TblDept();
    tblDept.setDeptId(16L);
    tblDept.setDeptName("分库");
    tblDept.setSId(6);
    tblDeptService.save(tblDept);

执行效果日志:
SpringBoot集成Sharding——JDBC分库分表

执行查询或插入代码:

	TblDept tblDept = new TblDept();
    tblDept.setDeptId(19L);
    tblDept.setDeptName("分库");
    tblDept.setSId(6);
    tblDeptService.save(tblDept);

执行效果日志:
SpringBoot集成Sharding——JDBC分库分表

转自:https://blog.csdn.net/s1078229131/article/details/106785894

上一篇:springboot sharding-jdbc分库分表


下一篇:sharding-jdbc分库使用