
ShardingSphere分库分表
shardingSphere 是一套开源的分布式数据库中间件解决方案,由 Apache 软件基金会孵化并维护。它提供了多种功能来增强传统数据库的能力,包括分库分表、读写分离、数据加密、分布式事务等。
shardingSphere主要分为两种Sharding-JDBC和Sharding-Proxy,其中Sharding-JDBC是轻量级 Java 客户端,适合作为微服务架构中的数据库访问层,以 JDBC 驱动形式提供,易于集成。而Sharding-Proxy是个中间件一样的适合非java语言接入shardingSphere,本文主要是介绍Sharding-JDBC在SpirngBoot中的使用。
引入maven包
<dependency>
<groupId>org.apache.shardingsphere</groupId>
<artifactId>shardingsphere-jdbc-core-spring-boot-starter</artifactId>
<version>5.1.1</version>
</dependency>
我这里使用的是5.x版本,和4.x版本据说有比较大的差异,不过我没有研究,后续再补充
配置文件
spring:
# 数据源配置
shardingsphere:
props:
sql-show: true
mode:
# 运行模式类型。可选配置:内存模式 Memory、单机模式 Standalone、集群模式 Cluster
type: Memory
datasource:
names: ds_0,ds_1,big_market #数据源名称列表
# 设置默认数据源
defaultDataSourceName: big_market
ds_0:
type: com.zaxxer.hikari.HikariDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/big_market_01....
username: root
password: 123456
ds_1:
type: com.zaxxer.hikari.HikariDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/big_market_02.....
username: root
password: 123456
big_market:
type: com.zaxxer.hikari.HikariDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/big_market...
username: root
password: 123456
rules:
sharding:
tables:
# 数据源配置配置需要分库分表的表名
raffle_activity_order:
actualDataNodes: ds_${0..1}.raffle_activity_order_00${0..3}
#分表
databaseStrategy:
standard:
#分库依据字段
shardingColumn: user_id
#分表库法名称
shardingAlgorithmName: sys_user_db_alg
#分表
tableStrategy:
standard:
#分表依据字段
shardingColumn: user_id
#分表依据字段
shardingAlgorithmName: sys_user_tbl_alg
# 分片算法配置
sharding-algorithms:
#算法名称
sys_user_db_alg:
#表示基于类实现的
type: CLASS_BASED
props:
#当分片规则基于单个分片键(Sharding Key)时,使用 standard 策略。
strategy: standard
#算法应用地址
algorithmClassName: cn.liuhl.config.MyDatabaseAlgorithm
#算法名称
sys_user_tbl_alg:
type: CLASS_BASED
props:
strategy: standard
algorithmClassName: cn.liuhl.config.MyTableAlgorithm#分表依据字段
配置文件比较多,一定要注意缩进,新版的idea会提示,如果出现波浪形证明配置错了,网上找了好多人的配置都是乱的,排查了挺久的问题的
分库分表算法类
package cn.liuhl.config;
import lombok.extern.slf4j.Slf4j;
import org.apache.shardingsphere.sharding.api.sharding.standard.PreciseShardingValue;
import org.apache.shardingsphere.sharding.api.sharding.standard.RangeShardingValue;
import org.apache.shardingsphere.sharding.api.sharding.standard.StandardShardingAlgorithm;
import org.springframework.stereotype.Component;
import java.util.Collection;
import java.util.Collections;
import java.util.Properties;
/**
* @author lhl
* @description 自定义分表算法
* @since 2025/3/31 下午2:53
*/
@Slf4j
public class MyTableAlgorithm implements StandardShardingAlgorithm<String> {
private Properties props;
@Override
public Properties getProps() {
return props;
}
@Override
public void init() {
log.info("分表算法加载");
this.props = props;
}
@Override
public String doSharding(Collection<String> collection, PreciseShardingValue<String> preciseShardingValue) {
int tableSize = collection.size();
// 真实表的前缀
String tablePrefix = preciseShardingValue.getDataNodeInfo().getPrefix();
// 分片健的值
long orderId = preciseShardingValue.getValue().hashCode() / 2;
// 对分片健取模后确定位置
long mod = orderId % tableSize;
return tablePrefix +"00"+ mod;
}
@Override
public Collection<String> doSharding(Collection<String> collection, RangeShardingValue<String> rangeShardingValue) {
return Collections.emptyList();
}
@Override
public String getType() {
return "sys_user_tbl_alg";
}
}
package cn.liuhl.config;
import lombok.extern.slf4j.Slf4j;
import org.apache.shardingsphere.sharding.api.sharding.standard.PreciseShardingValue;
import org.apache.shardingsphere.sharding.api.sharding.standard.RangeShardingValue;
import org.apache.shardingsphere.sharding.api.sharding.standard.StandardShardingAlgorithm;
import org.springframework.stereotype.Component;
import java.util.Collection;
import java.util.Collections;
import java.util.Properties;
/**
* @author lhl
* @description 自定义分库算法
* @since 2025/3/31 下午2:49
*/
@Slf4j
public class MyDatabaseAlgorithm implements StandardShardingAlgorithm<String> {
private Properties props;
@Override
public Properties getProps() {
return props;
}
@Override
public void init() {
log.info("分库算法加载");
this.props = props;
}
@Override
public String doSharding(Collection<String> collection, PreciseShardingValue<String> preciseShardingValue) {
int tableSize = collection.size();
// 真实表的前缀
String tablePrefix = preciseShardingValue.getDataNodeInfo().getPrefix();
// 分片健的值
long orderId = preciseShardingValue.getValue().hashCode();
// 对分片健取模后确定位置
long mod = orderId % tableSize;
return tablePrefix + mod;
}
@Override
public Collection<String> doSharding(Collection<String> collection, RangeShardingValue<String> rangeShardingValue) {
return Collections.emptyList();
}
@Override
public String getType() {
return "sys_user_db_alg";
}
}
目前我这个配置比较简单,主要就是按userId的hashCode进行取模计算,真实情况还得基于具体的业务去配置,这里只是做个参考。
单元测试
对于有分片的数据就插入到了具体的库表中
对于没有分片字段的sql就会走广播,也就是说会查询全部的库表
强制分片(指定数据库扫库)
后续。。。。
分库分表事务处理
后续。。。。
本文是原创文章,采用 CC BY-NC-ND 4.0 协议,完整转载请注明来自 Liuhlcloud.cn
评论
匿名评论
隐私政策
你无需删除空行,直接评论以获取最佳展示效果