종속성 설정
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>dynamic-datasource-spring-boot-starter</artifactId>
<version>3.6.1</version>
</dependency>
<dependency>
<groupId>org.apache.shardingsphere</groupId>
<artifactId>shardingsphere-jdbc-core-spring-boot-starter</artifactId>
<version>5.1.1</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.2.15</version>
</dependency>
데이터소스 구성
spring:
autoconfigure:
exclude: org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration
datasource:
url: jdbc:mysql://localhost:3306/primary_db?serverTimezone=UTC
username: admin
password: secure_pass
shardingsphere:
mode:
type: Memory
props:
sql-show: true
datasource:
names: shard_db
shard_db:
type: com.alibaba.druid.pool.DruidDataSource
url: jdbc:mysql://localhost:3306/shard_db?serverTimezone=UTC
username: shard_user
password: shard_pass
rules:
sharding:
tables:
transaction_log:
actual-data-nodes: shard_db.transaction_$->{2023..2024}
table-strategy:
standard:
sharding-column: log_date
sharding-algorithm-name: date-sharding
key-generate-strategy:
column: record_id
key-generator-name: id-generator
sharding-algorithms:
date-sharding:
type: DATE_BASED_SHARDING
props:
sharding-pattern: "transaction_$->{log_date.getYear()}"
key-generators:
id-generator:
type: SNOWFLAKE
데이터소스 통합 구성 클래스
@Configuration
@EnableConfigurationProperties(DynamicDataSourceProperties.class)
@AutoConfigureBefore({DynamicDataSourceAutoConfiguration.class})
public class DatasourceConfig {
@Autowired
private DynamicDataSourceProperties dsProps;
@Autowired
private DataSourceProperties primaryProps;
@Resource(name = "shardingSphereDataSource")
private AbstractDataSourceAdapter shardingDS;
@Bean
public DynamicDataSourceProvider dataSourceProvider() {
DataSourceProperty mainProperty = new DataSourceProperty();
mainProperty.setUrl(primaryProps.getUrl())
.setUsername(primaryProps.getUsername())
.setPassword(primaryProps.getPassword());
return new ShardingDSProvider(mainProperty, dsProps, shardingDS);
}
@Primary
@Bean
public DataSource dynamicDataSource() {
DynamicRoutingDataSource ds = new DynamicRoutingDataSource();
ds.setPrimary(dsProps.getPrimary());
return ds;
}
}
@AllArgsConstructor
class ShardingDSProvider extends AbstractDataSourceProvider {
private final DataSourceProperty mainProperty;
private final DynamicDataSourceProperties dsProps;
private final AbstractDataSourceAdapter shardingAdapter;
private static final String SHARD_DS_NAME = "shard_db";
@Override
public Map<String, DataSource> loadDataSources() {
Map<String, DataSourceProperty> properties = new HashMap<>();
properties.put(dsProps.getPrimary(), mainProperty);
properties.putAll(dsProps.getDatasource());
Map<String, DataSource> dsMap = createDataSourceMap(properties);
dsMap.put(SHARD_DS_NAME, shardingAdapter);
return dsMap;
}
}
사용자 정의 분할 알고리즘
public class DateBasedSharding implements StandardShardingAlgorithm<LocalDateTime> {
private String shardingPattern;
@Override
public void init() {
shardingPattern = getRequiredProperty("sharding-pattern");
}
@Override
public String doSharding(Collection<String> tables,
PreciseShardingValue<LocalDateTime> value) {
return evaluateExpression(value.getValue(), value.getColumnName());
}
@Override
public Collection<String> doSharding(Collection<String> tables,
RangeShardingValue<LocalDateTime> range) {
LocalDateTime start = range.getValueRange().lowerEndpoint();
LocalDateTime end = range.getValueRange().upperEndpoint();
List<String> matchedTables = new ArrayList<>();
int startYear = start.getYear();
int endYear = end.getYear();
for (int year = startYear; year <= endYear; year++) {
String tableName = "transaction_" + year;
if (tables.contains(tableName)) {
matchedTables.add(tableName);
}
}
return matchedTables.isEmpty() ? tables : matchedTables;
}
private String evaluateExpression(LocalDateTime date, String column) {
return shardingPattern.replace("$->{log_date.getYear()}",
String.valueOf(date.getYear()));
}
private String getRequiredProperty(String key) {
return Optional.ofNullable(props.getProperty(key))
.orElseThrow(() -> new IllegalArgumentException(key + " is required"));
}
}
알고리즘 등록
src/main/resources/META-INF/services/org.apache.shardingsphere.sharding.spi.ShardingAlgorithm 파일 생성 후:
com.example.DateBasedSharding
주요 고려사항
- 기존 데이터소스는 primary_db로 설정됨
- 분할 테이블 전용 데이터소스: shard_db
- 분할 키: log_date (LocalDateTime 타입)
- 분할 테이블 명명 규칙: transaction_YYYY