当前位置: 首页> 游戏> 单机 > Sharding-JDBC

Sharding-JDBC

时间:2025/8/10 9:21:28来源:https://blog.csdn.net/huantai3334/article/details/139655030 浏览次数:0次

一、概念:

        Sharding-JDBC是一个在客户端的分库分表工具。它是一个轻量级Java框架,在Java的JDBC层提供的额外服务。

        ShardingSphere提供标准化的数据分片、分布式事务和数据治理功能。

二、架构图:

  • ShardingRuleConfiguration 可以包含多个 TableRuleConfiguration(多张表),也可以设置默认的分库和分表策略。
  • 每个TableRuleConfiguration 可以针对表设置 ShardingStrategyConfiguration,包括分库分分表策略。
  • ShardingStrategyConfiguration 有 5 种实现(标准、行内、复合、Hint、无)
  • ShardingDataSourceFactory利用ShardingRuleConfiguration创建数据源。

三、基础概念:

逻辑表:

order_1、order_2、order_3

真实表:

order

数据节点:

数据分片的最小物理单元。由数据源名称和数据表组成,例: ds_0.order_0

绑定表:

指分片规则一致的主表和子表。例如: order和 t_order

广播表:

指所有的分片数据源中都存在的表,例如,字典表

分片策略:

包含分片键和分片算法;

  • 具体策略:
    • 标准分片策略(StandardShardingStrategy):用于处理 BETWEEN AND, >, =,
    • 复合分片策略(ComplexShardingStrategy):支持多分片键,提供对 SQL 语句中的 =, >, =,
    • 行表达式分片策略(InlineShardingStrategy): t_user_$->{u_id % 8} 表示 t_user 表根据 u_id 模 8,而分成 8 张表,表名称为 t_user_0 到 t_user_7
    • Hint分片策略(HintShardingStrategy):通过 Hint 指定分片值而非从 SQL 中提取分片值的方式进行分片的策略
    • 不分片策略(NoneShardingStrategy)
  • 分片键:用于分片的表字段
  • 分片算法:
    • 精确分片算法(单一分片键,例如 =、in)
    • 范围分片算法(单一分片键,例如 ETWEEN AND、>、=、
    • 复合分片算法(多片键)
    • Hint分片算法

主键生成策略:

通过在客户端生成自增主键替换以数据库原生自增主键的方式,做到分布式主键无重复。

四、执行流程:

SQL 解析 => 查询优化 => SQL路由 => SQL改写 => SQL执行 => 结果归并

五、使用方法:

---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- 
# pom.xml
<!--sharding-jdbc-->
<dependency><groupId>org.apache.shardingsphere</groupId><artifactId>sharding-jdbc-spring-boot-starter</artifactId><version>4.1.1</version>
</dependency>---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- 
# 自定义分片规则,需要Java SPI进行加载。
/*** 〈一句话功能简述〉<br>* 〈客户端用户表id自增生成〉** @author hanxinghua* @create 2022/6/10* @since 1.0.0*/
@Component
public class AppUserIdGenerator implements ShardingKeyGenerator {private RedisUtil redisUtil;@Overridepublic Comparable<?> generateKey() {if (redisUtil == null) {synchronized (this) {if (redisUtil == null) {redisUtil = SpringUtil.getBean("redisUtil");}}}return redisUtil.incr(AppUtil.APP_USER_ID, 1L);}@Overridepublic String getType() {return "APPUSERID";}@Overridepublic Properties getProperties() {return null;}@Overridepublic void setProperties(Properties properties) {}
}
Java SPI 地址:
src/main/resources/META-INF/services/org.apache.shardingsphere.spi.keygen.ShardingKeyGenerator
ShardingKeyGenerator内容:
com.hippo.online.config.shardingjdbc.AppUserIdGenerator---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- 
# 自定义分片规则
/*** 〈一句话功能简述〉<br>* 〈用户表分片规则〉** @author hanxinghua* @create 2022/6/13* @since 1.0.0*/
public class AppUserShardingAlgorithm implements PreciseShardingAlgorithm<Integer> {@Overridepublic String doSharding(Collection<String> targetTableNames, PreciseShardingValue<Integer> shardingValue) {String value = String.valueOf(shardingValue.getValue());for (String targetTableName : targetTableNames) {if (targetTableName.endsWith(value)) {return targetTableName;}}return "app_user_999";}
}
/*** 〈一句话功能简述〉<br>* 〈用户记录表分片规则〉** @author hanxinghua* @create 2022/6/13* @since 1.0.0*/
public class AppUserRecordShardingAlgorithm implements PreciseShardingAlgorithm<Integer> {@Overridepublic String doSharding(Collection<String> targetTableNames, PreciseShardingValue<Integer> shardingValue) {String value = String.valueOf(shardingValue.getValue());for (String targetTableName : targetTableNames) {if (targetTableName.endsWith(value)) {return targetTableName;}}return "app_user_record_999";}
}---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- 
# yaml配置:
spring:shardingsphere:# 数据源配置datasource:names: ds0ds0:type: com.alibaba.druid.pool.DruidDataSourcedriverClassName: com.mysql.cj.jdbc.Driver... ...    props:sql.show: true  # 打开sql输出日志sharding:defaultDataSourceName: ds0  # 默认数据源名称tables:# 逻辑表名称app_user:# 数据节点:数据源$->{0..N}.逻辑表名$->{0..N}actualDataNodes: ds0.app_user_$->{999..1011} # 现在是只分表不分库# 主键生成规则keyGenerator:column: idtype: APPUSERID # 自定义# 拆分表策略tableStrategy:standard:shardingColumn: app_idpreciseAlgorithmClassName: com.config.shardingjdbc.AppUserShardingAlgorithm# 逻辑表名称      app_user_record:actualDataNodes: ds0.app_user_record_$->{999..1011} # 现在是只分表不分库tableStrategy:standard:shardingColumn: app_idpreciseAlgorithmClassName: com.config.shardingjdbc.AppUserRecordShardingAlgorithm# 绑定表bindingTables: app_user,app_user_record# 表达式举例:
## ${begin..end}:表示范围区间
## ${[unit1, unit2, unit_x]}:表示枚举值
## db1.table_$->{[1,2]}
## t_user_$->{u_id % 8}:表示t_user表根据u_id模8,而分成8张表,表名称为t_user_0到t_user_7# 主键生成规则举例:
key-generator:column: idtype: SNOWFLAKE  #雪花算法props:work.id: 0  # 表示雪花id机器标识位,取值范围[0,1024)max.vibration.offset: 2 # 在高并发下,每次生成id都可能跨毫秒,夸毫秒,则序列部分会从0开始计算,每次生成的id都是偶数,奇偶分片有问题# 用于单分片键的标准分片举例:
spring.shardingsphere.sharding.tables.<logic-table-name>.database-strategy.standard.sharding-column= #分片列名称
spring.shardingsphere.sharding.tables.<logic-table-name>.database-strategy.standard.precise-algorithm-class-name= #精确分片算法类名称,用于=和IN。该类需实现PreciseShardingAlgorithm接口并提供无参数的构造器
spring.shardingsphere.sharding.tables.<logic-table-name>.database-strategy.standard.range-algorithm-class-name= #范围分片算法类名称,用于BETWEEN,可选。该类需实现RangeShardingAlgorithm接口并提供无参数的构造器# 用于多分片键的复合分片举例:
spring.shardingsphere.sharding.tables.<logic-table-name>.database-strategy.complex.sharding-columns= #分片列名称,多个列以逗号分隔
spring.shardingsphere.sharding.tables.<logic-table-name>.database-strategy.complex.algorithm-class-name= #复合分片算法类名称。该类需实现ComplexKeysShardingAlgorithm接口并提供无参数的构造器

六、多数据源配置:

# pom.xml:
<dependency><groupId>com.baomidou</groupId><artifactId>dynamic-datasource-spring-boot-starter</artifactId><version>3.2.1</version>
</dependency># 配置多数据源:
## 设置严格模式,默认false(不启动)。启动后在未匹配到指定数据源时候回抛出异常,不启动会使用默认数据源。
spring.datasource.dynamic.strict=true
## 设置默认的数据源或者数据源组,默认值即为master
spring.datasource.dynamic.primary=master
## 配置master数据源:
### 以下datasource相关,省略部分
spring.datasource.dynamic.datasource.master.type=
spring.datasource.dynamic.datasource.master.driverClassName =... ...
## 配置shardingsphere相关数据源:
### 以下datasource相关,省略部分
spring.shardingsphere.datasource.names=ds-1
spring.shardingsphere.datasource.ds-1.type=
spring.shardingsphere.datasource.ds-1.driverClassName=... ...
spring.shardingsphere.datasource.names=ds-2
spring.shardingsphere.datasource.ds-2.type=
spring.shardingsphere.datasource.ds-2.driverClassName=... ...# 数据源配置类:
/*** 〈一句话功能简述〉<br>* 〈配置数据源〉** @author hanxinghua* @create 2022/6/16* @since 1.0.0*/
@Configuration
@AutoConfigureBefore({DynamicDataSourceAutoConfiguration.class, SpringBootConfiguration.class})
public class DataSourceConfig {/*** 分表数据源名称*/public static final String SHARDING_DATA_SOURCE_NAME = "sharding";/*** 动态数据源配置项*/@Autowiredprivate DynamicDataSourceProperties dynamicDataSourceProperties;@Lazy@Resourceprivate DataSource shardingDataSource;@Beanpublic DynamicDataSourceProvider dynamicDataSourceProvider() {Map<String, DataSourceProperty> datasourceMap = dynamicDataSourceProperties.getDatasource();return new AbstractDataSourceProvider() {@Overridepublic Map<String, DataSource> loadDataSources() {Map<String, DataSource> dataSourceMap = createDataSourceMap(datasourceMap);// 将Sharding-jdbc管理的数据源也交给动态数据源管理dataSourceMap.put(SHARDING_DATA_SOURCE_NAME, shardingDataSource);return dataSourceMap;}};}@Bean@Primarypublic DataSource dataSource(DynamicDataSourceProvider dynamicDataSourceProvider) {DynamicRoutingDataSource dataSource = new DynamicRoutingDataSource();dataSource.setPrimary(dynamicDataSourceProperties.getPrimary());dataSource.setStrict(dynamicDataSourceProperties.getStrict());dataSource.setStrategy(dynamicDataSourceProperties.getStrategy());dataSource.setProvider(dynamicDataSourceProvider);dataSource.setP6spy(dynamicDataSourceProperties.getP6spy());dataSource.setSeata(dynamicDataSourceProperties.getSeata());return dataSource;}
}# 使用:访问没有分表的数据时使用默认的普通数据源,访问分表的数据时使用@DS("sharding")注解

七、数据迁移:

1.停机迁移(不推荐)

2.数据双写迁移

3.采用canal中间件迁移

关键字:Sharding-JDBC

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

责任编辑: