ShardingSphere 分片:Apache 分布式数据库生态
FreeGuideOnline
最新
2026-06-30
xml org.apache.shardingsphere shardingsphere-jdbc-core-spring-boot-starter 5.4.1 com.mysql mysql-connector-j
#### 配置分片规则
在 `application.yml` 中定义数据源和分片规则。示例按 `order_id` 分库分表,使用行表达式简化配置。
```yaml
spring:
shardingsphere:
datasource:
names: ds0,ds1
ds0:
type: com.zaxxer.hikari.HikariDataSource
driverClassName: com.mysql.cj.jdbc.Driver
jdbcUrl: jdbc:mysql://localhost:3306/demo_ds_0?serverTimezone=UTC
username: root
password: root
ds1:
type: com.zaxxer.hikari.HikariDataSource
driverClassName: com.mysql.cj.jdbc.Driver
jdbcUrl: jdbc:mysql://localhost:3306/demo_ds_1?serverTimezone=UTC
username: root
password: root
rules:
sharding:
# 分片算法配置
sharding-algorithms:
database-inline:
type: INLINE
props:
algorithm-expression: ds${order_id % 2}
table-inline:
type: INLINE
props:
algorithm-expression: t_order_${order_id % 2}
# 表规则
tables:
t_order:
actual-data-nodes: ds${0..1}.t_order_${0..1}
database-strategy:
standard:
sharding-column: order_id
sharding-algorithm-name: database-inline
table-strategy:
standard:
sharding-column: order_id
sharding-algorithm-name: table-inline
props:
sql-show: true # 开发时打印 SQL 便于调试
编写实体与数据操作
使用 Spring Data JPA 或 MyBatis 均可。以下为 JPA 示例:
@Entity
@Table(name = "t_order")
public class Order {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long orderId;
private Long userId;
private String status;
// getters / setters 省略
}
Repository:
public interface OrderRepository extends JpaRepository<Order, Long> {
}
测试分片效果
编写测试插入不同 order_id 的数据,观察数据是否路由到正确的库和表:
@SpringBootTest
class OrderTest {
@Autowired
private OrderRepository repository;
@Test
void testInsert() {
for (long i = 1; i <= 4; i++) {
Order order = new Order();
order.setOrderId(i);
order.setUserId(100 + i);
order.setStatus("NEW");
repository.save(order);
}
}
}
打开 SQL 日志,应能看到 Actual SQL 指向 ds0.t_order_1、ds1.t_order_0 等节点。
进阶分片策略配置
行表达式分片
使用 INLINE 算法并提供 Groovy 表达式,如上例 ds${order_id % 2},简洁但仅支持简单取模。
自定义精准分片
当分片逻辑复杂时需要自定义算法。实现 PreciseShardingAlgorithm 接口:
public class CustomDatabasePreciseAlgorithm implements PreciseShardingAlgorithm<Long> {
@Override
public String doSharding(Collection<String> availableTargetNames, PreciseShardingValue<Long> shardingValue) {
// 自定义规则,比如取哈希后映射到库名
long hash = shardingValue.getValue() % 4;
String target = "ds" + hash;
if (availableTargetNames.contains(target)) {
return target;
}
throw new UnsupportedOperationException();
}
}
在配置中引用该算法:
sharding-algorithms:
custom-db:
type: CLASS_BASED
props:
strategy: standard
algorithmClassName: com.example.CustomDatabasePreciseAlgorithm
范围分片
对于 BETWEEN AND 查询,需要实现 RangeShardingAlgorithm。内置 VOLUME_RANGE 算法支持基于范围的分片,但更常见的做法是结合自定义算法。
复合分片
当使用多个分片键时,实现 ComplexKeysShardingAlgorithm,在配置的 database-strategy 和 table-strategy 中指定 complex 策略。
Hint 强制路由
在某些场景下,分片键不在 SQL 中,需要通过编码指定路由。使用 HintManager:
HintManager hintManager = HintManager.getInstance();
hintManager.addDatabaseShardingValue("t_order", 1); // 强制路由到 ds1
hintManager.addTableShardingValue("t_order", 0); // 强制路由到 t_order_0
// 执行 SQL
hintManager.close(); // 务必关闭,避免线程泄露
对应的 Hint 算法需实现 HintShardingAlgorithm。
分布式场景中的常见问题
分布式主键生成
分片后不能沿用数据库自增主键。ShardingSphere 内置雪花算法(Snowflake)和 UUID 生成器。配置如下:
rules:
sharding:
key-generators:
snowflake:
type: SNOWFLAKE
tables:
t_order:
key-generate-strategy:
column: order_id
key-generator-name: snowflake