Apache ShardingSphere 是一款开源的分布式数据库中间件生态圈,由京东数科发起并贡献给 Apache 基金会。它定位为数据库的上层增强计算引擎,提供以下核心能力:
组件 | 说明 |
---|---|
ShardingSphere-JDBC | 轻量级 Java 框架,以 jar 包形式提供服务 |
ShardingSphere-Proxy | 透明化的数据库代理,支持异构语言 |
ShardingSphere-Sidecar | 云原生 sidecar 模式 (开发中) |
依赖配置 (pom.xml):
<dependency>
<groupId>org.apache.shardingsphere</groupId>
<artifactId>shardingsphere-jdbc-core-spring-boot-starter</artifactId>
<version>5.3.2</version>
</dependency>
application.yml 配置示例:
spring:
shardingsphere:
datasource:
names: ds0,ds1
ds0:
type: com.zaxxer.hikari.HikariDataSource
driver-class-name: com.mysql.jdbc.Driver
jdbc-url: jdbc:mysql://localhost:3306/ds0
username: root
password:
ds1:
type: com.zaxxer.hikari.HikariDataSource
driver-class-name: com.mysql.jdbc.Driver
jdbc-url: jdbc:mysql://localhost:3306/ds1
username: root
password:
rules:
sharding:
tables:
t_order:
actual-data-nodes: ds$->{0..1}.t_order_$->{0..15}
table-strategy:
standard:
sharding-column: order_id
precise-algorithm-class-name: com.example.MyPreciseShardingAlgorithm
自定义算法实现:
public class MyPreciseShardingAlgorithm implements StandardShardingAlgorithm<Long> {
@Override
public String doSharding(Collection<String> availableTargetNames,
PreciseShardingValue<Long> shardingValue) {
// 实现精确分片逻辑
long orderId = shardingValue.getValue();
return "t_order_" + (orderId % 16);
}
}
Spring Boot 启动类:
@SpringBootApplication
@MapperScan("com.example.mapper") // 如果使用MyBatis
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
扩展类型 | 接口 | 典型实现 |
---|---|---|
分片算法 | StandardShardingAlgorithm |
精确分片、范围分片 |
分布式ID生成 | KeyGenerateAlgorithm |
Snowflake、UUID |
加密算法 | EncryptAlgorithm |
AES、MD5 |
负载均衡 | ReplicaLoadBalanceAlgorithm |
轮询、随机 |
public class CustomRangeShardingAlgorithm implements RangeShardingAlgorithm<Long> {
@Override
public Collection<String> doSharding(Collection<String> availableTargetNames,
RangeShardingValue<Long> shardingValue) {
// 处理 BETWEEN AND 等范围查询的分片路由
Range<Long> range = shardingValue.getValueRange();
return availableTargetNames.stream()
.filter(table -> isInRange(table, range))
.collect(Collectors.toList());
}
private boolean isInRange(String tableName, Range<Long> range) {
// 实现具体范围判断逻辑
}
}
在 resources/META-INF/services
下创建文件:
org.apache.shardingsphere.sharding.spi.ShardingAlgorithm
内容为您的实现类全限定名:
com.example.CustomRangeShardingAlgorithm
场景 | 性能表现 | 说明 |
---|---|---|
单表查询 | 接近原生 | 无额外开销 |
跨库查询 | 取决于分片策略 | 需网络开销 |
批量插入 | 并行处理 | 比单库快 2-5 倍 |
聚合查询 | 有性能损耗 | 需合并多个分片结果 |
指标 | 单库 | ShardingSphere (4分片) |
---|---|---|
TPM-C | 3,200 | 11,500 |
平均延迟 | 12ms | 18ms |
吞吐量 | 1x | 3.6x |
缺点 | 影响 | 缓解方案 |
---|---|---|
分布式事务限制 | XA 性能较差,BASE 不完全一致 | 合理设计业务边界 |
复杂SQL支持有限 | 子查询、函数分片可能不支持 | 简化SQL或应用层处理 |
跨分片性能下降 | JOIN/ORDER BY 跨分片效率低 | 冗余字段或使用宽表 |
扩容复杂度高 | 需要数据迁移 | 提前规划分片策略 |
分片策略设计:
SQL限制:
运维挑战:
版本升级:
ShardingSphere 作为优秀的分布式数据库中间件,合理使用可以显著提升系统扩展性,但需要充分认识其限制并做好技术储备。