shardingsphere5.1.1分表分库yaml配置 自定义策略

文章详细介绍了ApacheShardingSphere的数据分片配置,包括基本配置示例和自定义策略。通过实际配置展示了如何根据user_id和id字段对数据进行分库分表。同时,文章提到了ShardingAlgorithm的重要性,解释了如PreciseShardingAlgorithm、RangeShardingAlgorithm、HintShardingAlgorithm和ComplexKeysShardingAlgorithm等分片算法的用途和场景,强调了它们在数据库扩展、数据隔离和负载均衡等方面的作用。
摘要由CSDN通过智能技术生成

前言

通过阅读官方稳定给出示例 https://shardingsphere.apache.org/document

一、基本配置示例

spring:
  sharding:
    datasource:
      names: ds0, ds1
      ds0:
        driver-class-name: com.mysql.jdbc.Driver
        url: jdbc:mysql://localhost:3306/db0
        username: root
        password: root
      ds1:
        driver-class-name: com.mysql.jdbc.Driver
        url: jdbc:mysql://localhost:3306/db1
        username: root
        password: root
    sharding:
      default-database-strategy:
        inline:
          sharding-column: user_id
          algorithm-expression: ds$->{user_id % 2}
      tables:
        user:
          actual-data-nodes: ds$->{0..1}.user_$->{0..1}
          database-strategy:
            inline:
              sharding-column: user_id
              algorithm-expression: ds$->{user_id % 2}
          table-strategy:
            inline:
              sharding-column: id
              algorithm-expression: user_$->{id % 2}

在该配置中,有两个数据源ds0和ds1,分别对应两个数据库db0和db1。在ShardingSphere中,通过配置actual-data-nodes属性来指定数据分片的具体情况。在这里,我们指定了user表在ds0和ds1这两个数据源中的分片情况。其中,actual-data-nodes中的$->{0..1}表示分片,即分为两个分片。

在分片策略中,我们采用了取模算法。对于user表,我们根据user_id字段的值对数据进行分片,具体的算法表达式为ds$->{user_id % 2}。这样就将user表的数据分为了两个数据源。

对于具体的分片表,我们还需要设置table-strategy,以实现分表的功能。在这里,我们根据id字段的值对数据进行分表,具体的算法表达式为user_$->{id % 2}。

二、自定义策略

官网策略规则(混合规则)

rules:
- !SHARDING
  tables: # 数据分片规则配置
    <logic_table_name> (+): # 逻辑表名称
      actualDataNodes (?): # 由数据源名 + 表名组成(参考 Inline 语法规则)
      databaseStrategy (?): # 分库策略,缺省表示使用默认分库策略,以下的分片策略只能选其一
        standard: # 用于单分片键的标准分片场景
          shardingColumn: # 分片列名称
          shardingAlgorithmName: # 分片算法名称
        complex: # 用于多分片键的复合分片场景
          shardingColumns: # 分片列名称,多个列以逗号分隔
          shardingAlgorithmName: # 分片算法名称
        hint: # Hint 分片策略
          shardingAlgorithmName: # 分片算法名称
        none: # 不分片
      tableStrategy: # 分表策略,同分库策略
      keyGenerateStrategy: # 分布式序列策略
        column: # 自增列名称,缺省表示不使用自增主键生成器
        keyGeneratorName: # 分布式序列算法名称
      auditStrategy: # 分片审计策略
        auditorNames: # 分片审计算法名称
          - <auditor_name>
          - <auditor_name>
        allowHintDisable: true # 是否禁用分片审计hint
  defaultDatabaseStrategy:
    standard:
      shardingColumn: # 分片列名称
      shardingAlgorithmName: # 分片算法名称
  # 分片算法配置
  shardingAlgorithms:
    <sharding_algorithm_name> (+): # 分片算法名称
      type: # 分片算法类型
      props: # 分片算法属性配置
      # ...https://shardingsphere.apache.org/document/current/cn/user-manual/common-config/builtin-algorithm/sharding/
  keyGenerators:
    <key_generate_algorithm_name> (+): # 分布式序列算法名称
      type: # 分布式序列算法类型
      props: # 分布式序列算法属性配置
- !READWRITE_SPLITTING
  dataSources:
    <data_source_name>: # 读写分离逻辑数据源名称
      dynamicStrategy: # 读写分离类型
        autoAwareDataSourceName: # 数据库发现逻辑数据源名称
    <data_source_name>: # 读写分离逻辑数据源名称
      dynamicStrategy: # 读写分离类型
        autoAwareDataSourceName: # 数据库发现逻辑数据源名称
- !DB_DISCOVERY
  dataSources:
    <data_source_name>:
      dataSourceNames: # 数据源名称列表
        - ds_0
        - ds_1
        - ds_2
      discoveryHeartbeatName: # 检测心跳名称
      discoveryTypeName: # 数据库发现类型名称
    <data_source_name>:
      dataSourceNames: # 数据源名称列表
        - ds_3
        - ds_4
        - ds_5
      discoveryHeartbeatName: # 检测心跳名称
      discoveryTypeName: # 数据库发现类型名称
  discoveryHeartbeats:
    <discovery_heartbeat_name>: # 心跳名称
      props:
        keep-alive-cron: # cron 表达式,如:'0/5 * * * * ?'
  discoveryTypes:
    <discovery_type_name>: # 数据库发现类型名称
      type: # 数据库发现类型,如:MySQL.MGR 
      props:
        group-name:  # 数据库发现类型必要参数,如 MGR 的 group-name
- !ENCRYPT
  encryptors:
    <encrypt_algorithm_name> (+): # 加解密算法名称
      type: # 加解密算法类型
      props: # 加解密算法属性配置
    <encrypt_algorithm_name> (+): # 加解密算法名称
      type: # 加解密算法类型
  tables:
    <table_name>: # 加密表名称
      columns:
        <column_name> (+): # 加密列名称
          plainColumn (?): # 原文列名称
          cipherColumn: # 密文列名称
          encryptorName: # 密文列加密算法名称
          assistedQueryColumn (?):  # 查询辅助列名称
          assistedQueryEncryptorName:  # 查询辅助列加密算法名称
          likeQueryColumn (?):  # 模糊查询列名称
          likeQueryEncryptorName:  # 模糊查询列加密算法名称
      queryWithCipherColumn(?): # 该表是否使用加密列进行查询
spring:
  shardingsphere:
    mode:
      # 运行模式类型。可选配置:内存模式 Memory、单机模式 Standalone、集群模式 Cluster
      type: Memory
    props:
      #是否在日志中打印 SQL。
      #打印 SQL 可以帮助开发者快速定位系统问题。日志内容包含:逻辑 SQL,真实 SQL 和 SQL 解析结果。
      #如果开启配置,日志将使用 Topic ShardingSphere-SQL,日志级别是 INFO。 false
      sql-show: true
      #是否在日志中打印简单风格的 SQL。false
      sql-simple: false
      #用于设置任务处理线程池的大小。每个 ShardingSphereDataSource 使用一个独立的线程池,同一个 JVM 的不同数据源不共享线程池。
      executor-size: 20
      #次查询请求在每个数据库实例中所能使用的最大连接数。1
      max-connections-size-per-query: 1
      #在程序启动和更新时,是否检查分片元数据的结构一致性。
      check-table-metadata-enabled: false
      #在程序启动和更新时,是否检查重复表。false
      check-duplicate-table-enabled: false
    datasource:
      names: ds0, ds1
      ds0:
        driver-class-name: com.mysql.jdbc.Driver
        url: jdbc:mysql://localhost:3306/db0
        username: root
        password: root
      ds1:
        driver-class-name: com.mysql.jdbc.Driver
        url: jdbc:mysql://localhost:3306/db1
        username: root
        password: root
    rules:
      sharding:
        key-generators:
          # shardingsphere-jdbc-core-spring-boot-starter需要加载此项配置  
          snowflake:
            type: SNOWFLAKE
            props:
              worker-id: 123
        #分片算法配置
        sharding-algorithms:
          ## 分片算法名称
          fenpian-db-1:
            #对应 Override getType
            type: UserDatabaseAlgorithm
            # 分片算法属性配置
            props:
              strategy: STANDARD
              algorithm-class-name: xxxx.xxx.xxx.UserDatabaseAlgorithm
          fenpian-table-1:
            #对应 Override getType
            type: UserDataTableAlgorithm
            props:
              strategy: STANDARD
              algorithm-class-name: xxxxx.xxxx.xxx.UserDataTableAlgorithm
        
        tables:
          # 逻辑表名称
          sys_user:
            # 由数据源名 + 表名组成(参考 Inline 语法规则)
            actual-data-nodes: ds${0..3}.sys_user${0..255}
            # 分表策略,缺省表示使用默认分库策略,以下的分片策略只能选其一
            table-strategy:
              #standard: # 用于单分片键的标准分片场景
              standard:
                #数据库的键
                shardingColumn: xxxx
                sharding-algorithm-name: fenpian-table-1
            # 分库策略,缺省表示使用默认分库策略,以下的分片策略只能选其一
            database-strategy:
              #standard: # 用于单分片键的标准分片场景
              standard:
                shardingColumn: xxxx
                # 此处使用的就是我们在sharding-algorithms里面定义的规则
                sharding-algorithm-name: fenpian-db-1
public class UserDatabaseAlgorithm implements StandardShardingAlgorithm<Long> {

    @Override
    public String doSharding(Collection<String> databaseNames, PreciseShardingValue<Long> shardingValue) {
        for (String databaseName : databaseNames) {
            if (databaseName.endsWith(String.valueOf(shardingValue.getValue() % 2))) {
                return databaseName;
            }
        }
        throw new IllegalArgumentException();
    }

    @Override
    public String getType() {
        return "UserDatabaseAlgorithm";
    }
}
public class UserDataTableAlgorithm implements StandardShardingAlgorithm<Long> {

    @Override
    public String doSharding(Collection<String> databaseNames, PreciseShardingValue<Long> shardingValue) {
        for (String databaseName : databaseNames) {
            if (databaseName.endsWith(String.valueOf(shardingValue.getValue() % 2))) {
                return databaseName;
            }
        }
        throw new IllegalArgumentException();
    }

    @Override
    public String getType() {
        return "UserDataTableAlgorithm";
    }
}

SPI机制注入

org.apache.shardingsphere.sharding.spi.ShardingAlgorithm

xxxx.xxx.xxx.UserDatabaseAlgorithm
xxxxx.xxxx.xxx.UserDataTableAlgorithm

搞完收工!!!!!

三、ShardingAlgorithm实现类扩展

在ShardingSphere中,ShardingAlgorithm是一个非常重要的概念,是分片规则中实现分片算法的核心接口。ShardingAlgorithm接口定义了如何根据分片键的值计算分片后的数据所在位置。ShardingSphere提供了多种ShardingAlgorithm的实现类,下面是常见的几种实现类及其区别:

PreciseShardingAlgorithm

PreciseShardingAlgorithm是ShardingSphere提供的最基本的分片算法接口,用于实现基于精确值的分片算法。PreciseShardingAlgorithm只能用于处理精确的分片键,即单个值,无法处理范围查询。使用PreciseShardingAlgorithm进行分片时,只需要在规则配置中指定算法名称,即可实现数据的分片。

用于将数据按照一定规则分散到不同的数据库和表中。它的实现可以用于以下场景:
数据库扩展:当一个单一数据库无法满足应用程序的性能需求时,可以使用分库分表技术,将数据分散到多个数据库和表中,以提高性能。
数据隔离:某些业务需要数据隔离,例如多租户应用程序中,每个租户的数据需要独立存储,这时可以使用分库分表技术。
数据容错:当某个数据库或表发生故障时,分库分表可以通过备份或者替换该节点,从而提高应用程序的容错性。
数据负载均衡:使用分库分表可以将数据分散到不同的节点上,从而实现数据的负载均衡,提高应用程序的性能和稳定性。

RangeShardingAlgorithm

RangeShardingAlgorithm是ShardingSphere提供的另一种常见的分片算法接口,用于实现基于范围的分片算法。RangeShardingAlgorithm能够处理范围查询,支持处理>、>=、<、<=、BETWEEN AND等操作符。使用RangeShardingAlgorithm进行分片时,需要指定范围查询的最小值和最大值,以及需要查询的具体分片键范围,从而计算出符合要求的分片结果。

它可以根据一定的范围规则,将数据按照分片键的范围进行分散到不同的数据库和表中。通过 RangeShardingAlgorithm,可以实现数据的按范围划分,从而更好地控制数据的分布和负载均衡。
实现 RangeShardingAlgorithm 有以下用途:
数据分片更加灵活:通过 RangeShardingAlgorithm,可以根据分片键的范围规则,将数据按照一定的范围进行分片,从而更加灵活地控制数据的分布和负载均衡。
数据查询更加高效:由于 RangeShardingAlgorithm 可以将数据按照分片键的范围进行划分,因此在查询数据时可以更加高效地进行范围查询,从而提高查询性能。
数据备份和恢复更加容易:使用 RangeShardingAlgorithm 可以将数据按照范围进行备份和恢复,从而提高数据的可用性和容错能力。
数据库扩展更加灵活:通过 RangeShardingAlgorithm,可以将新的数据库或表添加到分片规则中,从而实现动态扩展。
总的来说,RangeShardingAlgorithm 可以为应用程序提供更加灵活、更加高效的数据分片方式,满足不同的业务需求。但是需要注意的是,在使用 RangeShardingAlgorithm 时需要对分片规则进行更加严格的管理,以确保数据分散均匀且查询性能高效。同时,需要考虑范围划分的复杂度和性能,以确保系统的性能和可扩展性。

HintShardingAlgorithm

HintShardingAlgorithm是一种比较特殊的分片算法,它不需要分片键,而是通过ShardingHint对象中携带的分片信息进行数据的分片。使用HintShardingAlgorithm进行分片时,需要在SQL语句中加入hint信息,例如/*+ sharding(shardingValue=xxx) */,其中shardingValue为hint的名称,xxx为具体的分片信息。这种算法相对于其他算法来说,可以灵活地指定分片信息,但需要在代码中显式地添加hint信息。

以根据用户指定的分片键,将数据按照一定规则分散到不同的数据库和表中。与 PreciseShardingAlgorithm 不同,HintShardingAlgorithm 不需要通过计算分片键的哈希值来进行分片,而是通过应用程序显式指定分片路由信息,从而实现数据的分片。
实现 HintShardingAlgorithm 有以下用途:
灵活性更高:通过 HintShardingAlgorithm,应用程序可以显式指定数据的分片路由信息,从而可以更灵活地进行分片。
特殊业务需求:某些业务需要将数据存储到指定的数据库或表中,例如某些敏感数据需要存储到特定的数据库或表中,此时可以使用 HintShardingAlgorithm 实现数据的分片。
数据库扩展:当应用程序需要进行数据库扩展时,通过 HintShardingAlgorithm 可以将新的数据库或表添加到分片规则中,从而实现动态扩展。
数据备份和恢复:通过 HintShardingAlgorithm,可以将数据备份到指定的数据库或表中,从而方便进行数据恢复和灾备。
总的来说,HintShardingAlgorithm 可以为应用程序提供更灵活、更精细的数据分片方式,满足不同的业务需求。但是需要注意的是,由于需要应用程序显式指定分片路由信息,因此在使用 HintShardingAlgorithm 时需要进行更为严格的分片规划和管理,否则可能会出现数据分散不均或者数据丢失等问题。

ComplexKeysShardingAlgorithm

ComplexKeysShardingAlgorithm是一种用于处理多分片键的复合分片算法,它能够根据多个分片键计算出分片后的数据所在位置。使用ComplexKeysShardingAlgorithm进行分片时,需要指定多个分片键,以及如何计算这些分片键的值。相比于单一分片键的分片算法,ComplexKeysShardingAlgorithm可以提供更为灵活的分片策略。

总的来说,ShardingSphere提供了多种ShardingAlgorithm的实现类,每种实现类都有其特点和适用场景。开发人员需要根据具体业务需求,选择适合的分片算法,以实现高效、灵活、可靠的数据分片。

它可以根据多个分片键,将数据按照一定规则分散到不同的数据库和表中。相比于单一的分片键,使用多个分片键可以更加精细地控制数据的分片方式,从而实现更好的负载均衡和容错能力。
实现 ComplexKeysShardingAlgorithm 有以下用途:
数据分片更加精细:通过使用多个分片键,可以将数据按照更为复杂的规则进行分片,从而更加精细地控制数据的分布和负载均衡。
业务逻辑更加复杂:某些业务需要根据多个分片键来进行数据分片,例如一个订单系统需要根据订单创建时间和订单状态来进行分片,此时可以使用 ComplexKeysShardingAlgorithm 实现数据分片。
数据库扩展更加灵活:通过使用多个分片键,可以将新的数据库或表添加到分片规则中,从而实现动态扩展。
数据备份和恢复更加容易:使用多个分片键可以更加精细地控制数据的备份和恢复,从而提高数据的可用性和容错能力。
总的来说,ComplexKeysShardingAlgorithm 可以为应用程序提供更加灵活、更加精细的数据分片方式,满足不同的业务需求。但是需要注意的是,由于需要考虑多个分片键之间的关系,因此在使用 ComplexKeysShardingAlgorithm 时需要进行更为严格的分片规划和管理,否则可能会出现数据分散不均或者数据丢失等问题。同时,实现 ComplexKeysShardingAlgorithm 也需要考虑算法的复杂度和性能,以确保系统的性能和可扩展性。

StandardShardingAlgorithm

StandardShardingAlgorithm是ShardingSphere提供的一种分片算法接口实现,它是基于分片键进行分片的一种标准分片算法。使用StandardShardingAlgorithm进行分片时,需要指定分片键的值、分片表的数量以及分片后的数据表名称,从而计算出分片后的数据所在位置。

标准化
由于StandardShardingAlgorithm是ShardingSphere提供的标准分片算法之一,因此开发人员可以基于该算法进行二次开发,快速实现自己的分片算法,同时也可以避免重复造轮子。
灵活性
StandardShardingAlgorithm支持自定义分片策略,可以根据不同的业务需求,制定不同的分片策略。开发人员可以通过修改StandardShardingAlgorithm的实现来适应不同的分片场景,如按时间、按地域、按用户等。
易用性
StandardShardingAlgorithm接口定义简单明了,易于使用和理解。开发人员只需要实现该接口中的doSharding方法,就可以实现自己的分片算法。此外,由于StandardShardingAlgorithm是ShardingSphere提供的标准分片算法,因此可以直接在ShardingSphere中配置,无需进行额外的代码开发。
总的来说,StandardShardingAlgorithm提供了一种通用的分片算法实现方式,能够帮助开发人员快速实现分布式系统的数据分片,提高系统的可扩展性和性能。开发人员可以根据具体业务需求,选择合适的分片算法,以实现高效、灵活、可靠的数据分片。
以下是一个基本的 Shardingsphere 分库分表 demo 配置: 1. 引入依赖 首先需要在项目中引入 Shardingsphere 的相关依赖,具体版本号可根据需求自行选择。 ```xml <!-- ShardingSphere JDBC Core APIs --> <dependency> <groupId>org.apache.shardingsphere</groupId> <artifactId>sharding-core-jdbc</artifactId> <version>${sharding.version}</version> </dependency> <!-- ShardingSphere JDBC Spring Boot Starter --> <dependency> <groupId>org.apache.shardingsphere</groupId> <artifactId>sharding-jdbc-spring-boot-starter</artifactId> <version>${sharding.version}</version> </dependency> ``` 2. 配置数据源 在 application.yml 中配置数据源信息,包括主库和从库的信息。 ```yml spring: datasource: # 主库数据源 master: jdbc-url: jdbc:mysql://localhost:3306/master_db?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC username: root password: 123456 driver-class-name: com.mysql.jdbc.Driver # 从库数据源 slave1: jdbc-url: jdbc:mysql://localhost:3306/slave_db1?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC username: root password: 123456 driver-class-name: com.mysql.jdbc.Driver slave2: jdbc-url: jdbc:mysql://localhost:3306/slave_db2?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC username: root password: 123456 driver-class-name: com.mysql.jdbc.Driver ``` 3. 配置分库分表规则 在 application.yml 中配置分库分表规则,包括分库规则和分表规则。 ```yml sharding: # 分库规则 default-database-strategy: standard: sharding-column: user_id precise-algorithm-class-name: com.example.demo.algorithm.ModuloDatabaseShardingAlgorithm # 分表规则 tables: user: actual-data-nodes: master.user_${0..1} table-strategy: standard: sharding-column: id precise-algorithm-class-name: com.example.demo.algorithm.ModuloTableShardingAlgorithm ``` 其中,ModuloDatabaseShardingAlgorithm 和 ModuloTableShardingAlgorithm 是自定义分库分表算法,这里只是简单示例。 4. 编写 DAO 层代码 在 DAO 层编写相应的代码,使用 ShardingSphere 提供的 API 完成数据库操作,例如: ```java @Repository public class UserDaoImpl implements UserDao { private final JdbcTemplate jdbcTemplate; @Autowired public UserDaoImpl(JdbcTemplate jdbcTemplate) { this.jdbcTemplate = jdbcTemplate; } @Override public User getById(Long id) { String sql = "SELECT * FROM user WHERE id = ?"; return jdbcTemplate.queryForObject(sql, new Object[]{id}, new BeanPropertyRowMapper<>(User.class)); } @Override public void save(User user) { String sql = "INSERT INTO user(id, user_id, name) VALUES (?, ?, ?)"; jdbcTemplate.update(sql, user.getId(), user.getUserId(), user.getName()); } } ``` 5. 测试分库分表效果 编写测试代码,测试分库分表的效果,例如: ```java @SpringBootTest class UserDaoImplTest { @Autowired private UserDao userDao; @Test void testSave() { User user = new User(); user.setId(1L); user.setUserId(1L); user.setName("张三"); userDao.save(user); } @Test void testGetById() { User user = userDao.getById(1L); System.out.println(user); } } ``` 至此,一个简单的 Shardingsphere 分库分表 demo 配置就完成了。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值