在Spring Boot项目中集成ShardingSphere实现分库分表,可以帮助你轻松实现数据库的水平拆分。ShardingSphere是一个开源的分布式数据库中间件,支持分库分表、读写分离、分布式事务等功能。可以按照以下步骤进行配置和实现。以下是详细的配置和说明:
1. 引入依赖
在pom.xml
中添加ShardingSphere和数据库连接池的依赖。注意,ShardingSphere已经内置了数据源管理功能,因此不需要额外引入druid-spring-boot-starter
,而是直接使用druid。
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>2.5.3</version>
<exclusions>
<exclusion>
<artifactId>snakeyaml</artifactId>
<groupId>org.yaml</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.4.3.3</version>
<exclusions>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.32</version>
</dependency>
<dependency>
<groupId>org.apache.shardingsphere</groupId>
<artifactId>shardingsphere-jdbc-core-spring-boot-starter</artifactId>
<version>5.2.1</version>
<exclusions>
<exclusion>
<artifactId>snakeyaml</artifactId>
<groupId>org.yaml</groupId>
</exclusion>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
<version>2.5.3</version>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.3.3</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.28</version>
</dependency>
<dependency>
<groupId>org.yaml</groupId>
<artifactId>snakeyaml</artifactId>
<version>1.33</version>
</dependency>
<!--引入shardingJDBC后,就不要直接使用druid-sprint-boot-starter依赖了。
因为这个依赖会在Spring容器中注入一个DataSource,这样再要使用ShardingSphere注入DataSource就会产生冲突了。-->
<!--<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.20</version>
</dependency>-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.20</version>
</dependency>
</dependencies>
2. 配置数据源和分库分表规则
在application.yml
中配置数据源和分库分表规则。以下是一个示例配置:
spring:
shardingsphere:
datasource:
names: db0,db1
db0:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/game0?useUnicode=true&characterEncoding=utf8&useSSL=true&serverTimezone=GMT%2B8
username: root
password: 123456
db1:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/game1?useUnicode=true&characterEncoding=utf8&useSSL=true&serverTimezone=GMT%2B8
username: root
password: 123456
rules:
sharding:
tables:
t_order:
actual-data-nodes: db$->{0..1}.t_order_$->{1..2}
key-generate-strategy:
column: id
key-generator-name: snowflake
database-strategy:
standard:
sharding-column: user_id
sharding-algorithm-name: database_inline
table-strategy:
standard:
sharding-column: id
sharding-algorithm-name: table_inline
sharding-algorithms:
database_inline:
type: INLINE
props:
algorithm-expression: db$->{user_id % 2}
table_inline:
type: INLINE
props:
algorithm-expression: t_order_${id % 2 + 1}
allow-range-query-with-inline-sharding: true
key-generators:
snowflake:
type: SNOWFLAKE
props:
sql-show: true
mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
3.配置说明
- 数据源配置:
datasource.names
定义了两个数据源 db0
和 db1
。分别指向 game0和 game1数据库。
- 分片规则配置:
-
t_order 表被配置为分片表
。 -
actual-data-nodes
:定义实际的数据节点,db$->{0..1}.t_order_$->{0..1}
表示:数据分布在db0
和db1
两个库中,每个库中有t_order_1
和t_order_2
两张表。 -
key-generate-strategy
:定义主键生成策略,使用 Snowflake 算法生成分布式主键ID。
-
database-strategy
:定义分库策略,根据user_id
分库,使用database_inline
算法。 -
table-strategy
:定义分表策略,根据id分表,使用table_inline
算法。
-
- 分片算法配置:
-
使用database_inline
:INLINE
表达式分库,根据user_id%2
的值决定数据落在db0
还是db1
。例如:user_id%2 == 0
→db0,user_id%2 == 1
→db1。
-
使用table_inline
:INLINE
表达式分表,根据id%2+1
的值决定数据落在t_order_1
还是t_order_2
。例如:id%2+1 == 2
→t_order_2
,id%2+1 == 1
→t_order_1。
allow-range-query-with-inline-sharding:true
允许范围查询(如BETWEEN
、>
、<
等)。
-
4.ShardingPhere核心概念
4.1 垂直分片和水平分片
垂直分片:表示按照业务维度,将不同的表拆分到不同的库中。减少每个数据库的数据量以及客户端的连接数,提高查询效率。
水平分片:表示按照数据纬度,将原本存在同一张表中的数据,拆分到多张子表当中。
4.2 虚拟库
ShardingSphere的核心就是提供一个具备分库分表功能的虚拟库,他是一个
ShardingSphereDatasource实例。应用程序只需要像操作单数据源一样访问这ShardingSphereDatasource即可。
4.3 真实库
实际保存数据的数据库。这些数据库都被包含在ShardingSphereDatasource实例当中,由
ShardingSphere决定未来需要使用哪个真实库。
4.4 逻辑表
应用程序直接操作的逻辑表。
4.5 真实表
实际保存数据的表。这些真实表与逻辑表表名不需要一致,但是需要有相同的表结构,可以分布在不同的真实库中。
4.6 分布式主键生成算法
给逻辑表生成唯一主键。由于逻辑表的数据是分布在多个真实表当中的,所有单表的索引就无法保证逻辑表的ID唯一性。ShardingSphere集成了几种常见的基于单机生成的分布式主键生成器。比如SNOWFLAKE雪花算法可以生成单调递增的long类型的数字主键。
4.7 分片策略
表示逻辑表要如何分配到真实库和真实表当中,分为分库策略和分表策略两个部分。分片策略由分片键和分片算法组成。分片键是进行数据水平拆分的关键字段,分片算法表示根据分片键如何寻找对应的真实库和真实表。
5. 测试分库分表
@Data
public class Order {
private Long id;
/**
* 订单号
*/
private String orderNo;
/**
* 用户id
*/
private Long userId;
}
@Mapper
public interface OrderMapper extends BaseMapper<Order> {
/**
* 新增订单
*
* @param userId
* @param orderNo
* @return
*/
@Insert("INSERT INTO t_order (user_id, order_no) VALUES(#{userId},#{orderNo})")
int insertOrder(@Param("userId") Long userId, @Param("orderNo") String orderNo);
/**
* 查询订单详情
*
* @param id
* @param userId
* @return
*/
Order detail(@Param("id") Long id, @Param("userId") Long userId);
}
5.1 插入操作和查询操作
@RestController
@RequestMapping("/order")
public class OrderController {
@Resource
private OrderMapper orderMapper;
@PostMapping("/insert")
public Object insertOrder(@RequestBody OrderAddReq req) {
for (int i = 0; i < 10; i++) {
orderMapper.insertOrder(500L + i, "新订单"+i);
}
return Boolean.TRUE;
}
@GetMapping("/detail")
public Object detail(Long id, Long userId) {
Order order = orderMapper.detail(id, userId);
return order;
}
}
5.2 验证日志
- 插入数据日志
- 查询数据日志
6. 注意事项
-
表结构一致性:确保 db0 和 db1 数据库中的 t_order 表结构一致。
-
分布式事务:如果需要支持分布式事务,可以考虑集成Seata等分布式事务解决方案。
-
分片算法:ShardingSphere提供了多种分片算法(如范围分片、哈希分片等),可以根据业务需求选择合适的算法。例如STANDARD(标准分片算法)、COMPLEX_INLINE(复杂分片算法)、CLASS_BASED(自定义分片算法)、HINT_INLINE(强制分片算法)。
通过以上步骤,你可以在Spring Boot项目中成功集成ShardingSphere,实现分库分表的功能。如果遇到问题,可以根据日志进一步排查。