前言
通过阅读官方稳定给出示例 https://shardingsphere.apache.org/document
一、基本配置示例
spring:sharding:datasource:names: ds0, ds1ds0:driver-class-name: com.mysql.jdbc.Driverurl: jdbc:mysql://localhost:3306/db0username: rootpassword: rootds1:driver-class-name: com.mysql.jdbc.Driverurl: jdbc:mysql://localhost:3306/db1username: rootpassword: rootsharding:default-database-strategy:inline:sharding-column: user_idalgorithm-expression: ds$->{user_id % 2}tables:user:actual-data-nodes: ds$->{0..1}.user_$->{0..1}database-strategy:inline:sharding-column: user_idalgorithm-expression: ds$->{user_id % 2}table-strategy:inline:sharding-column: idalgorithm-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:- !SHARDINGtables: # 数据分片规则配置 (+): # 逻辑表名称actualDataNodes (?): # 由数据源名 + 表名组成(参考 Inline 语法规则)databaseStrategy (?): # 分库策略,缺省表示使用默认分库策略,以下的分片策略只能选其一standard: # 用于单分片键的标准分片场景shardingColumn: # 分片列名称shardingAlgorithmName: # 分片算法名称complex: # 用于多分片键的复合分片场景shardingColumns: # 分片列名称,多个列以逗号分隔shardingAlgorithmName: # 分片算法名称hint: # Hint 分片策略shardingAlgorithmName: # 分片算法名称none: # 不分片tableStrategy: # 分表策略,同分库策略keyGenerateStrategy: # 分布式序列策略column: # 自增列名称,缺省表示不使用自增主键生成器keyGeneratorName: # 分布式序列算法名称auditStrategy: # 分片审计策略auditorNames: # 分片审计算法名称- - allowHintDisable: true # 是否禁用分片审计hintdefaultDatabaseStrategy:standard:shardingColumn: # 分片列名称shardingAlgorithmName: # 分片算法名称# 分片算法配置shardingAlgorithms: (+): # 分片算法名称type: # 分片算法类型props: # 分片算法属性配置# ...https://shardingsphere.apache.org/document/current/cn/user-manual/common-config/builtin-algorithm/sharding/keyGenerators: (+): # 分布式序列算法名称type: # 分布式序列算法类型props: # 分布式序列算法属性配置- !READWRITE_SPLITTINGdataSources:: # 读写分离逻辑数据源名称dynamicStrategy: # 读写分离类型autoAwareDataSourceName: # 数据库发现逻辑数据源名称: # 读写分离逻辑数据源名称dynamicStrategy: # 读写分离类型autoAwareDataSourceName: # 数据库发现逻辑数据源名称- !DB_DISCOVERYdataSources::dataSourceNames: # 数据源名称列表- ds_0- ds_1- ds_2discoveryHeartbeatName: # 检测心跳名称discoveryTypeName: # 数据库发现类型名称:dataSourceNames: # 数据源名称列表- ds_3- ds_4- ds_5discoveryHeartbeatName: # 检测心跳名称discoveryTypeName: # 数据库发现类型名称discoveryHeartbeats:: # 心跳名称props:keep-alive-cron: # cron 表达式,如:'0/5 * * * * ?'discoveryTypes:: # 数据库发现类型名称type: # 数据库发现类型,如:MySQL.MGR props:group-name:# 数据库发现类型必要参数,如 MGR 的 group-name- !ENCRYPTencryptors: (+): # 加解密算法名称type: # 加解密算法类型props: # 加解密算法属性配置 (+): # 加解密算法名称type: # 加解密算法类型tables:: # 加密表名称columns: (+): # 加密列名称plainColumn (?): # 原文列名称cipherColumn: # 密文列名称encryptorName: # 密文列加密算法名称assistedQueryColumn (?):# 查询辅助列名称assistedQueryEncryptorName:# 查询辅助列加密算法名称likeQueryColumn (?):# 模糊查询列名称likeQueryEncryptorName:# 模糊查询列加密算法名称queryWithCipherColumn(?): # 该表是否使用加密列进行查询spring:shardingsphere:mode:# 运行模式类型。可选配置:内存模式 Memory、单机模式 Standalone、集群模式 Clustertype: Memoryprops:#是否在日志中打印 SQL。#打印 SQL 可以帮助开发者快速定位系统问题。日志内容包含:逻辑 SQL,真实 SQL 和 SQL 解析结果。#如果开启配置,日志将使用 Topic ShardingSphere-SQL,日志级别是 INFO。 falsesql-show: true#是否在日志中打印简单风格的 SQL。falsesql-simple: false#用于设置任务处理线程池的大小。每个 ShardingSphereDataSource 使用一个独立的线程池,同一个 JVM 的不同数据源不共享线程池。executor-size: 20#次查询请求在每个数据库实例中所能使用的最大连接数。1max-connections-size-per-query: 1#在程序启动和更新时,是否检查分片元数据的结构一致性。check-table-metadata-enabled: false#在程序启动和更新时,是否检查重复表。falsecheck-duplicate-table-enabled: falsedatasource:names: ds0, ds1ds0:driver-class-name: com.mysql.jdbc.Driverurl: jdbc:mysql://localhost:3306/db0username: rootpassword: rootds1:driver-class-name: com.mysql.jdbc.Driverurl: jdbc:mysql://localhost:3306/db1username: rootpassword: rootrules:sharding:key-generators:# shardingsphere-jdbc-core-spring-boot-starter需要加载此项配置 snowflake:type: SNOWFLAKEprops:worker-id: 123#分片算法配置sharding-algorithms: ## 分片算法名称fenpian-db-1:#对应 Override getTypetype: UserDatabaseAlgorithm# 分片算法属性配置props:strategy: STANDARDalgorithm-class-name: xxxx.xxx.xxx.UserDatabaseAlgorithmfenpian-table-1:#对应 Override getTypetype: UserDataTableAlgorithmprops:strategy: STANDARDalgorithm-class-name: xxxxx.xxxx.xxx.UserDataTableAlgorithmtables: # 逻辑表名称sys_user:# 由数据源名 + 表名组成(参考 Inline 语法规则)actual-data-nodes: ds${0..3}.sys_user${0..255}# 分表策略,缺省表示使用默认分库策略,以下的分片策略只能选其一table-strategy: #standard: # 用于单分片键的标准分片场景standard:#数据库的键shardingColumn: xxxxsharding-algorithm-name: fenpian-table-1# 分库策略,缺省表示使用默认分库策略,以下的分片策略只能选其一database-strategy: #standard: # 用于单分片键的标准分片场景standard:shardingColumn: xxxx# 此处使用的就是我们在sharding-algorithms里面定义的规则sharding-algorithm-name: fenpian-db-1
public class UserDatabaseAlgorithm implements StandardShardingAlgorithm {@Overridepublic String doSharding(Collection databaseNames, PreciseShardingValue shardingValue) {for (String databaseName : databaseNames) {if (databaseName.endsWith(String.valueOf(shardingValue.getValue() % 2))) {return databaseName;}}throw new IllegalArgumentException();}@Overridepublic String getType() {return "UserDatabaseAlgorithm";}}
public class UserDataTableAlgorithm implements StandardShardingAlgorithm {@Overridepublic String doSharding(Collection databaseNames, PreciseShardingValue shardingValue) {for (String databaseName : databaseNames) {if (databaseName.endsWith(String.valueOf(shardingValue.getValue() % 2))) {return databaseName;}}throw new IllegalArgumentException();}@Overridepublic String getType() {return "UserDataTableAlgorithm";}}
SPI机制注入
org.apache.shardingsphere.sharding.spi.ShardingAlgorithm
xxxx.xxx.xxx.UserDatabaseAlgorithmxxxxx.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提供了一种通用的分片算法实现方式,能够帮助开发人员快速实现分布式系统的数据分片,提高系统的可扩展性和性能。开发人员可以根据具体业务需求,选择合适的分片算法,以实现高效、灵活、可靠的数据分片。