动态分库分表
1.方案简述
动态分库+取模分表的方式,解决扩容时数据迁移,分表数据热点问题。
根据数据库配置的规则来计算会路由到哪个数据库里面去。例:我对user表进行了分库分表。当user数据量小于30我就只插入db0这个数据库。大于30小于60我就插入db1这个数据库。
id | start | end | db_name |
---|---|---|---|
1 | 1 | 30 | db0 |
2 | 31 | 60 | db1 |
如果数据量超过60,我就再建一个数据库db2,并且在这个规则表里加一条数据就行了
id | start | end | db_name |
---|---|---|---|
1 | 1 | 30 | db0 |
2 | 31 | 60 | db1 |
3 | 61 | 90 | db2 |
2.pom.xml
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.0.1</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.16</version>
</dependency>
<dependency>
<groupId>org.apache.shardingsphere</groupId>
<artifactId>sharding-jdbc-spring-boot-starter</artifactId>
<version>4.0.0-RC1</version>
</dependency>
<!-- <dependency>
<groupId>io.shardingjdbc</groupId>
<artifactId>sharding-jdbc-spring-boot-starter</artifactId>
<version>2.0.0.M3</version>
</dependency> -->
</dependencies>
3.配置文件
server.port=8084
mybatis.config-location=classpath:META-INF/mybatis-config.xml
spring.shardingsphere.datasource.names=master0,master0slave,master1,master1slave
# 数据源
spring.shardingsphere.datasource.master0.type=com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.master0.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.master0.url=jdbc:mysql://localhost:3306/ds_0?characterEncoding=utf-8
spring.shardingsphere.datasource.master0.username=root
spring.shardingsphere.datasource.master0.password=0490218292
spring.shardingsphere.datasource.master0slave.type=com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.master0slave.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.master0slave.url=jdbc:mysql://localhost:3306/ds_0_slave?characterEncoding=utf-8
spring.shardingsphere.datasource.master0slave.username=root
spring.shardingsphere.datasource.master0slave.password=0490218292
spring.shardingsphere.datasource.master1.type=com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.master1.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.master1.url=jdbc:mysql://localhost:3306/ds_1?characterEncoding=utf-8
spring.shardingsphere.datasource.master1.username=root
spring.shardingsphere.datasource.master1.password=0490218292
spring.shardingsphere.datasource.master1slave.type=com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.master1slave.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.master1slave.url=jdbc:mysql://localhost:3306/ds_1_slave?characterEncoding=utf-8
spring.shardingsphere.datasource.master1slave.username=root
spring.shardingsphere.datasource.master1slave.password=0490218292
# 分表配置
spring.shardingsphere.sharding.tables.user.actual-data-nodes=ds$->{0..1}.user_$->{0..2}
spring.shardingsphere.sharding.tables.user.table-strategy.inline.sharding-column=id
spring.shardingsphere.sharding.tables.user.table-strategy.inline.algorithm-expression=user_$->{id % 3}
# 分库配置
spring.shardingsphere.sharding.default-database-strategy.standard.sharding-column=id
spring.shardingsphere.sharding.default-database-strategy.standard.precise-algorithm-class-name=com.cxytiandi.sharding.algorithm.MyPreciseShardingAlgorithm
# 读写分离
spring.shardingsphere.sharding.master-slave-rules.ds0.master-data-source-name=master0
spring.shardingsphere.sharding.master-slave-rules.ds0.slave-data-source-names=master0slave
spring.shardingsphere.sharding.master-slave-rules.ds1.master-data-source-name=master1
spring.shardingsphere.sharding.master-slave-rules.ds1.slave-data-source-names=master1slave
spring.shardingsphere.props.sql.show=true
4.自定义的分片算法
/**
* 自定义分片算法
*
* @author mmc
*
*/
public class MyPreciseShardingAlgorithm implements PreciseShardingAlgorithm<Long> {
@Override
public String doSharding(Collection<String> availableTargetNames, PreciseShardingValue<Long> shardingValue) {
Long id = shardingValue.getValue();
ShareDbService shareDbService = SpringUtil.getBean(ShareDbService.class);
List<String> dbs = shareDbService.getDbById(id);
if(dbs!=null&&dbs.size()>0){
return dbs.get(0);
}
throw new IllegalArgumentException("找不到数据库:"+id);
}
}