Sharding-JDBC说明
Sharding-JDBC 是一个基于 JDBC 的数据库中间件,旨在为高并发的数据库应用提供分布式数据库访问和数据共享服务。Sharding-JDBC 主要适用于以下场景:
- 数据库水平拆分:当单个数据库无法满足业务需求,需要将数据水平拆分到多个数据库或表中进行存储。使用 Sharding-JDBC 可以通过配置来实现数据的自动分片,使得访问多个数据库或表时像访问单个数据库或表一样简单。
- 数据库读写分离:在高并发的读写操作场景下,使用 Sharding-JDBC 可以将数据库的读操作和写操作分离到不同的数据库实例中,减轻单台数据库的负担,提升了系统的扩展性和可用性。
- 数据库多租户:当多个客户需要共享同一套 SaaS 应用时,可以使用 Sharding-JDBC 来将这些客户的数据分散到不同的数据库或表中,从而避免了数据混杂和数据泄露的风险。
- 异地多活:异地多活是指在不同的地区建立多个数据中心,以实现数据备份、容灾等功能。使用 Sharding-JDBC 可以将数据库的读写操作分布到多个数据中心中,实现数据的多活复制,并保证数据的一致性。
Sharding-JDBC 主要适用于分布式数据库、高并发、多租户和异地多活等场景。通过 Sharding-JDBC 的自动分片、读写分离、负载均衡、透明化访问等特性,可以实现更高效、更可靠的数据库应用程序。
环境准备
依赖
<dependency>
<groupId>org.apache.shardingsphere</groupId>
<artifactId>sharding-jdbc-spring-boot-starter</artifactId>
<version>4.0.0-RC1</version>
</dependency>
水平分表
配置文件
定义数据源
# 定义数据源
spring.shardingsphere.datasource.names = m1
# 在配置信息中以数据源名称为前缀指明数据源与配置信息的对应关系
spring.shardingsphere.datasource.m1.type = com.alibaba.druid.pool.DruidDataSource
spring.shardingsphere.datasource.m1.driver‐class‐name = com.mysql.jdbc.Driver
spring.shardingsphere.datasource.m1.url = jdbc:mysql://localhost:3306/order_dbuseUnicode=true
spring.shardingsphere.datasource.m1.username = root
spring.shardingsphere.datasource.m1.password = 123456
指定表的数据分布情况,配置数据节点(inline表达式)
# 指定t_order表的数据分布情况,配置数据节点
spring.shardingsphere.sharding.tables.t_order.actual-data-nodes= m1.t_order_$‐>{1..2}
# 指定t_order表的主键生成策略为SNOWFLAKE
# 分库分表中,数据库表需要指定一个主键作为分片键,用来实现数据水平切分
spring.shardingsphere.sharding.tables.t_order.key-generator.column= order_id
spring.shardingsphere.sharding.tables.t_order.key-generator.type= SNOWFLAKE
# 指定t_order表的分片策略,分片策略包括分片键和分片算法
spring.shardingsphere.sharding.tables.t_order.table-strategy.inline.sharding-column= order_id
# 指定分片算法 表示将t_order 逻辑表按照 order_id 字段进行水平分片,分成两个实际物理表 t_order_1 和 t_order_2。如果order_id 取模运算的结果为 0,则将该行数据路由到 t_order_1 表中,否则将其路由到 t_order_2 表中。
spring.shardingsphere.sharding.tables.t_order.table-strategy.inline.algorithm-expression = t_order_$‐>{order_id % 2 + 1}
t_order_$‐>{1…2}表示t_order_1,t_order_2
${begin…end}表示范围区间
${[unit1,unit2,unit3]}表示枚举值
行表达式中如果出现连续多个 ${ expression } 或 $->{ expression } 表达式,整个表达式最终的结果将会根据每个表达式的结果进笛卡尔组合。
例如,以下⾏表达式:${[user1,user2]}_table{1…3}
最终会解析为:
user1_table1,user1_table2,user1_table3,user2_table1,user2_table2,user2_table3
指定表的数据分布情况,自定义分表算法
# 自定义分表算法
spring.shardingsphere.sharding.tables.user.table-strategy.standard.sharding-column=order_id
# 指定分片算法类
spring.shardingsphere.sharding.tables.user.table-strategy.standard.precise-algorithm-class-name=com.cxytiandi.sharding.algorithm.MyPreciseShardingAlgorithm
算法类
通过实现 PreciseShardingAlgorithm 接口,并重写其中的 doSharding() 方法,可以自定义分库分表的具体逻辑
/**
1. 实现PreciseShardingAlgorithm<Long>表示该类用于对 Long 类型的分片键进行精确分片算法。
*/
public class ShardingAlgorithm implements PreciseShardingAlgorithm<Long> {
@Override
public String doSharding(Collection<String> availableTargetNames, PreciseShardingValue<Long> shardingValue) {
for (String targetName : availableTargetNames) {
if (targetName.endsWith("_" + shardingValue.getValue() % 2)) {
return targetName;
}
}
throw new IllegalArgumentException("无法确定分片数据源");
}
}
水平分库
配置文件
#配置多个数据源
# 配置数据源名称,以逗号分隔
spring.shardingsphere.datasource.names = ds0, ds1
#在配置信息中以数据源名称为前缀指明数据源与配置信息的对应关系
# 配置数据源 0 的信息
spring.shardingsphere.datasource.ds0.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.ds0.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.ds0.url=jdbc:mysql://localhost:3306/db0
spring.shardingsphere.datasource.ds0.username=root
spring.shardingsphere.datasource.ds0.password=123456
# 配置数据源 1 的信息
spring.shardingsphere.datasource.ds1.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.ds1.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.ds1.url=jdbc:mysql://localhost:3307/db1
spring.shardingsphere.datasource.ds1.username=root
spring.shardingsphere.datasource.ds1.password=123456
# 分库策略,以user_id为分片键,分片策略为user_id % 2 + 1,user_id为偶数操作m1数据源,否则操作m2。
spring.shardingsphere.sharding.tables.t_order.database-strategy.inline.sharding-column = user_id
spring.shardingsphere.sharding.tables.t_order.database-strategy.inline.algorithm-expression = m$->{ user_id % 2+1}
# 指定t_order表的分片策略,分片策略包括分片键和分片算法
spring.shardingsphere.sharding.tables.t_order.table-strategy.inline.sharding-column = order_id
spring.shardingsphere.sharding.tables.t_order.table-strategy.inline.algorithm-expression = t_order_$->{order_id % 2 + 1}
# 指定t_order表的主键生成策略为SNOWFLAKE
spring.shardingsphere.sharding.tables.t_order.key-generator.column=order_id
spring.shardingsphere.sharding.tables.t_order.key-generator.type=SNOWFLAKE
执行流程
- 解析sql,获取片键值。
- 通过分片算法获取表名。
- 通过表名改写sql语句。
- 执行改写后的sql语句。
- 将执行sql的结果进行汇总合并,并返回。