Sharding Sphere教程


一、分库分表

1. 基本介绍

随着业务的不断增加,应用程序所存储的数据也将随之增长,对于传统的关系型数据而言,当单表的数据达到一定量级之后增删改效率也会有一定程度的降低,分库分表的需求也就应运而生。

2. 垂直分表

对于分表而言存在两种方式,这里先介绍一下垂直分表的实现逻辑。

垂直分表即将一张宽表进行纵向拆分,将使用频次较低的数据外置通过外键实现关联,从而降低单个数据表的大小,进而提高 SQL 的执行效率。

假如存在如下一张 user 表,其表结构与数据内容如下:

通过纵向拆分,可以将低频字段如 address 外提至 user_info 表,将利用外键 u_id 实现与 user 表的关联,拆分后得到下述两张用户表。

3. 水平分表

水平分表即将同样为将一张数据表拆分为多张数据表,但与垂直分表不同的是每张表的结构一致,通过特定的算法确定一条记录的归属。

最常见的分表策略即取模分表,即以主键或其它唯一标识字段为依据,通过该字段求模取余得到值确定记录的归属,对于非数值字段可执行哈希后再进行计算。

如将 user 表拆分为 user_1user_2 两张表,即可通过 id 主键与 2 求模取余,得到的结果若为 1 则存入 user_1,否则存入 user_2,按照此逻辑拆分即可得到下述两张表:

二、工程集成

1. 依赖导入

Sharding SphereApache 基金会下的开源分库分表中间件,旨在提供便利的分表分表实现。

这里就不过阐述其背景而专注于具体实现,首先在 Spring Boot 工程中引入下述依赖。

<dependency>
    <groupId>org.apache.shardingsphere</groupId>
    <artifactId>sharding-jdbc-spring-boot-starter</artifactId>
    <version>4.1.1</version>
</dependency>
<dependency>
    <groupId>org.apache.shardingsphere</groupId>
    <artifactId>shardingsphere-jdbc-core-spring-boot-starter</artifactId>
    <version>5.2.1</version>
</dependency>
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid</artifactId>
    <version>1.0.31</version>
</dependency>
<dependency>
    <groupId>org.yaml</groupId>
    <artifactId>snakeyaml</artifactId>
    <version>1.33</version>
</dependency>

2. 测试数据

在开始之前需要先准备好测试数据库与表,新建两个数据库 test_db1test_db2,并分别在两个库下创建下述两张表。

CREATE TABLE `user_info_1`
(
    `id`          int(11) NOT NULL,
    `name`        varchar(100) DEFAULT NULL,
    `gender`      varchar(100) DEFAULT NULL,
    `update_time` datetime     DEFAULT NULL,
    PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

CREATE TABLE `user_info_2`
(
    `id`          int(11) NOT NULL AUTO_INCREMENT,
    `name`        varchar(100) DEFAULT NULL,
    `gender`      varchar(100) DEFAULT NULL,
    `update_time` datetime     DEFAULT NULL,
    PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

3. 工程创建

完成数据库的资源新建之后,通过工具生成对应的代码,工程代码结构如下:

三、基本配置

1. 服务模式

shardingsphere 提供多种服务启动模式,如下 Standalone 表示单体启动,同理还有 Cluster 集群模式。

spring:
  shardingsphere:
    mode:
      type: Standalone
      repository:
        type: JDBC

2. 日志配置

通过下述配置开启执行的 SQL 语句日志输出,与 MyBatis 中的 mybatis.configuration.log-impl 配置项效果类似。

spring:
  shardingsphere:
    # 日志显示具体的SQL
    props:
      sql-show: true

四、数据分库

1. 连接配置

通过 spring.shardingsphere.datasource 配置生效的数据源连接配置,names 用于指定数据源名称。

spring:
  shardingsphere:
    # 配置数据库连接信息
    datasource:
      names: ds0, ds1
      ds0:
        type: com.alibaba.druid.pool.DruidDataSource
        driver-class-name: com.mysql.jdbc.Driver
        url: jdbc:mysql://localhost:3306/test_db1?useUnicode=true&characterEncoding=utf-8&useSSL=false
        username: root
        password: 123456
      ds1:
        type: com.alibaba.druid.pool.DruidDataSource
        driver-class-name: com.mysql.jdbc.Driver
        url: jdbc:mysql://localhost:3306/test_db2?useUnicode=true&characterEncoding=utf-8&useSSL=false
        username: root
        password: 123456

2. 分片规则

通过 rules 配置生效的分片规则,通过 actual-data-nodes 配置实际生效的资源表,database-strategy 用于配置分库策略,sharding-algorithm-name 取的值为 sharding-algorithms 中所定义的策略。

spring:
  shardingsphere:
    # 配置分片规则
    rules:
      sharding:
        # 配置所有分片表
        tables:
          # 配置表名
          user_info:
            # 声明表所在的数据节点
            actual-data-nodes: ds$->{0..1}.user_info_1
            # 配置分库规则
            database-strategy:
              standard:
                # 配置分库的路由键
                sharding-column: id
                # 配置分片算法,指向具体的策略
                sharding-algorithm-name: db-inline

        # 定义分片算法
        sharding-algorithms:
          db-inline:
            # 使用自定义表达式
            type: inline
            props:
              algorithm-expression: ds$->{id % 2}.user_info1

3. inline表达式

这里着重介绍一下 inline 表达式的语法,在上述配置中的 $->{} 即为 inline 表达式,其语法规则如下:

ds0, ds1
==> ds$->{0..1}
==> ds$->{['0','1']}

五、数据分表

1. 连接配置

分表的数据源连接配置与分库类似,配置如下:

spring:
  shardingsphere:
    # 配置数据库连接信息
    datasource:
      names: ds0
      ds0:
        type: com.alibaba.druid.pool.DruidDataSource
        driver-class-name: com.mysql.jdbc.Driver
        url: jdbc:mysql://localhost:3306/test_db1?useUnicode=true&characterEncoding=utf-8&useSSL=false
        username: root
        password: 123456

2. 分片规则

通过 rules 配置生效的分片规则,注意其中的 user_info 配置的为逻辑表名,若数据库存在表 user_info_1user_info_2 则需要配置为 user_info

spring:
  shardingsphere:
    # 配置分片规则
    rules:
      sharding:
        # 配置所有分片表
        tables:
          # 配置表名
          user_info:
            # 声明表所在的数据节点
            actual-data-nodes: ds0.user_info_$->{1..2}
            # 配置分表规则
            table-strategy:
              standard:
                # 配置分表的路由键
                sharding-column: id
                # 策略算法名称
                sharding-algorithm-name: user-inline

        # 定义分片算法
        sharding-algorithms:
          user-inline:
            # 使用自定义表达式
            type: inline
            props:
              algorithm-expression: user_info_$->{(id % 2) == 0 ? 2:1}

文章作者: 烽火戏诸诸诸侯
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 烽火戏诸诸诸侯 !
  目录