温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

如何使用分库分表Sharding-JDBC

发布时间:2021-10-21 17:18:21 来源:亿速云 阅读:326 作者:iii 栏目:编程语言
# 如何使用分库分表Sharding-JDBC ## 目录 - [一、分库分表核心概念](#一分库分表核心概念) - [1.1 什么是分库分表](#11-什么是分库分表) - [1.2 垂直拆分与水平拆分](#12-垂直拆分与水平拆分) - [1.3 分库分表适用场景](#13-分库分表适用场景) - [二、Sharding-JDBC架构解析](#二sharding-jdbc架构解析) - [2.1 核心组件与工作原理](#21-核心组件与工作原理) - [2.2 与MyCat对比](#22-与mycat对比) - [2.3 版本演进与新特性](#23-版本演进与新特性) - [三、基础环境搭建](#三基础环境搭建) - [3.1 依赖配置](#31-依赖配置) - [3.2 数据源配置](#32-数据源配置) - [3.3 分片规则配置](#33-分片规则配置) - [四、分片策略详解](#四分片策略详解) - [4.1 标准分片策略](#41-标准分片策略) - [4.2 复合分片策略](#42-复合分片策略) - [4.3 Hint分片策略](#43-hint分片策略) - [4.4 不分片策略](#44-不分片策略) - [五、分布式事务实现](#五分布式事务实现) - [5.1 XA事务](#51-xa事务) - [5.2 Seata柔性事务](#52-seata柔性事务) - [5.3 BASE事务](#53-base事务) - [六、实战案例](#六实战案例) - [6.1 电商订单分库分表](#61-电商订单分库分表) - [6.2 多租户SAAS系统](#62-多租户saas系统) - [6.3 物联网时序数据](#63-物联网时序数据) - [七、性能优化](#七性能优化) - [7.1 路由优化](#71-路由优化) - [7.2 合并执行优化](#72-合并执行优化) - [7.3 连接池配置](#73-连接池配置) - [八、运维监控](#八运维监控) - [8.1 指标监控集成](#81-指标监控集成) - [8.2 链路追踪](#82-链路追踪) - [8.3 慢查询分析](#83-慢查询分析) - [九、常见问题解决方案](#九常见问题解决方案) - [9.1 分布式ID生成](#91-分布式id生成) - [9.2 跨库JOIN处理](#92-跨库join处理) - [9.3 分布式序列问题](#93-分布式序列问题) - [十、未来发展趋势](#十未来发展趋势) - [10.1 云原生支持](#101-云原生支持) - [10.2 多模异构支持](#102-多模异构支持) - [10.3 智能化方向](#103-智能化方向) ## 一、分库分表核心概念 ### 1.1 什么是分库分表 分库分表是数据库水平扩展的核心技术手段,主要解决单机数据库在数据量增长时出现的性能瓶颈问题。当单表数据量超过500万行或数据库实例QPS超过3000时,就应该考虑分库分表方案。 **技术本质**:通过数据分片(Sharding)将数据集分散到不同的物理节点,使每个节点只处理部分数据,从而提升整体系统的处理能力。 ### 1.2 垂直拆分与水平拆分 #### 垂直拆分(Vertical Partitioning) ```sql -- 原始用户表 CREATE TABLE user ( id BIGINT, username VARCHAR(50), password VARCHAR(100), profile_json TEXT, login_log TEXT ); -- 拆分后 CREATE TABLE user_basic ( id BIGINT, username VARCHAR(50), password VARCHAR(100) ); CREATE TABLE user_profile ( user_id BIGINT, profile_json TEXT ); 

水平拆分(Horizontal Partitioning)

// 按用户ID范围分片 shardingRuleConfig.getTableRuleConfigs().add( TableRuleConfiguration.builder("t_order") .actualDataNodes("ds${0..1}.t_order_${0..15}") .databaseShardingStrategy( new StandardShardingStrategyConfiguration("user_id", "dbShardingAlgorithm")) .tableShardingStrategy( new StandardShardingStrategyConfiguration("order_id", "tableShardingAlgorithm")) .build()); 

1.3 分库分表适用场景

场景类型 典型特征 解决方案
高并发读写 QPS > 5000 分库分散压力
大数据量存储 单表 > 500万行 分表存储
地理分布式访问 跨地域访问延迟高 按地域分库
多租户系统 租户数据隔离需求 按租户ID分库

二、Sharding-JDBC架构解析

2.1 核心组件与工作原理

graph TD A[应用代码] --> B[Sharding-JDBC Driver] B --> C[SQL解析引擎] C --> D[路由引擎] D --> E[改写引擎] E --> F[执行引擎] F --> G[结果归并] G --> H[返回结果] 

关键组件说明: 1. SQL解析:基于Apache Calcite实现SQL语法树解析 2. 路由引擎:支持精确路由、范围路由、广播路由等多种模式 3. 执行引擎:自动建立多线程执行管道 4. 归并引擎:支持流式归并、内存归并等多种方式

2.2 与MyCat对比

特性 Sharding-JDBC MyCat
架构模式 客户端直连 代理层
性能损耗 % 15%-20%
功能完整性 分片+分布式事务 分片+集群管理
运维复杂度 低(无中间件) 高(需维护代理)
版本迭代 活跃(Apache维护) 社区维护

2.3 版本演进与新特性

5.x版本重大改进: 1. 可插拔架构:支持SPI扩展 2. 分布式事务:XA/SAGA/SEATA全支持 3. 数据加密:列级别透明加密 4. 影子库压测:全链路压测支持

三、基础环境搭建

3.1 依赖配置

Maven核心依赖:

<dependency> <groupId>org.apache.shardingsphere</groupId> <artifactId>shardingsphere-jdbc-core</artifactId> <version>5.3.2</version> </dependency> <dependency> <groupId>com.zaxxer</groupId> <artifactId>HikariCP</artifactId> <version>4.0.3</version> </dependency> 

Spring Boot自动配置:

spring.shardingsphere.datasource.names=ds0,ds1 spring.shardingsphere.datasource.ds0.type=com.zaxxer.hikari.HikariDataSource spring.shardingsphere.datasource.ds0.jdbc-url=jdbc:mysql://localhost:3306/ds0 spring.shardingsphere.datasource.ds0.username=root spring.shardingsphere.datasource.ds0.password=123456 

3.2 数据源配置

YAML格式配置示例:

spring: shardingsphere: datasource: names: ds0,ds1 ds0: type: com.zaxxer.hikari.HikariDataSource driver-class-name: com.mysql.jdbc.Driver jdbc-url: jdbc:mysql://localhost:3306/ds0 username: root password: 123456 connection-timeout: 30000 idle-timeout: 600000 max-lifetime: 1800000 maximum-pool-size: 20 

3.3 分片规则配置

Java API配置方式:

// 分片算法配置 Properties dbShardingProps = new Properties(); dbShardingProps.setProperty("algorithm-expression", "ds${user_id % 2}"); ShardingSphereAlgorithmConfiguration dbShardingAlgorithm = new ShardingSphereAlgorithmConfiguration("INLINE", dbShardingProps); // 表规则配置 ShardingTableRuleConfiguration orderTableRule = new ShardingTableRuleConfiguration( "t_order", "ds${0..1}.t_order_${0..15}"); orderTableRule.setDatabaseShardingStrategy( new StandardShardingStrategyConfiguration("user_id", "dbShardingAlgorithm")); orderTableRule.setTableShardingStrategy( new StandardShardingStrategyConfiguration("order_id", "tableShardingAlgorithm")); 

四、分片策略详解

4.1 标准分片策略

精确分片算法实现:

public class OrderDatabaseShardingAlgorithm implements PreciseShardingAlgorithm<Long> { @Override public String doSharding(Collection<String> availableTargetNames, PreciseShardingValue<Long> shardingValue) { for (String each : availableTargetNames) { if (each.endsWith(shardingValue.getValue() % 2 + "")) { return each; } } throw new IllegalArgumentException(); } } 

范围分片算法示例:

public class OrderRangeShardingAlgorithm implements RangeShardingAlgorithm<Long> { @Override public Collection<String> doSharding(Collection<String> availableTargetNames, RangeShardingValue<Long> shardingValue) { Set<String> result = new LinkedHashSet<>(); Long lower = shardingValue.getValueRange().lowerEndpoint(); Long upper = shardingValue.getValueRange().upperEndpoint(); for (long i = lower; i <= upper; i++) { for (String each : availableTargetNames) { if (each.endsWith(i % 2 + "")) { result.add(each); } } } return result; } } 

4.2 复合分片策略

多字段分片配置:

spring: shardingsphere: sharding: tables: t_order: actual-data-nodes: ds$->{0..1}.t_order_$->{0..15} database-strategy: complex: sharding-columns: user_id,order_date algorithm-class-name: com.example.ComplexShardingAlgorithm 

复合算法实现:

public class ComplexShardingAlgorithm implements ComplexKeysShardingAlgorithm<Comparable<?>> { @Override public Collection<String> doSharding(Collection<String> availableTargetNames, ComplexKeysShardingValue<Comparable<?>> shardingValue) { Map<String, Collection<Comparable<?>>> columnValues = shardingValue.getColumnNameAndShardingValuesMap(); Collection<Comparable<?>> userIds = columnValues.get("user_id"); Collection<Comparable<?>> orderDates = columnValues.get("order_date"); Set<String> result = new HashSet<>(); // 实现自定义复合分片逻辑 for (Comparable<?> userId : userIds) { for (Comparable<?> orderDate : orderDates) { int dbSuffix = (userId.hashCode() & Integer.MAX_VALUE) % 2; int tableSuffix = orderDate.hashCode() % 16; result.add(String.format("ds%d.t_order_%d", dbSuffix, tableSuffix)); } } return result; } } 

4.3 Hint分片策略

强制路由配置:

// 设置分片值 HintManager.getInstance().setDatabaseShardingValue(1); try { // 执行SQL(将强制路由到ds1) orderRepository.selectAll(); } finally { HintManager.clear(); } 

Hint算法实现:

public class OrderHintShardingAlgorithm implements HintShardingAlgorithm<Integer> { @Override public Collection<String> doSharding(Collection<String> availableTargetNames, HintShardingValue<Integer> shardingValue) { Collection<String> result = new ArrayList<>(); for (String each : availableTargetNames) { for (Integer value : shardingValue.getValues()) { if (each.endsWith(value.toString())) { result.add(each); } } } return result; } } 

4.4 不分片策略

广播表配置:

spring: shardingsphere: sharding: broadcast-tables: t_config 

绑定表配置:

spring: shardingsphere: sharding: binding-tables: - t_order,t_order_item 

五、分布式事务实现

5.1 XA事务

配置XA事务管理器:

spring: shardingsphere: props: xa-transaction-manager-type: Atomikos 

事务使用示例:

@ShardingSphereTransactionType(TransactionType.XA) @Transactional public void placeOrder(Order order) { // 业务逻辑 } 

5.2 Seata柔性事务

Seata集成配置:

spring: shardingsphere: props: seata: tx-service-group: my_test_tx_group 

AT模式示例:

@ShardingSphereTransactionType(TransactionType.BASE) @Transactional public void updateOrder(Order order) { // 第一阶段:执行业务SQL并生成undo log orderMapper.update(order); // 第二阶段:由Seata自动提交/回滚 } 

5.3 BASE事务

Saga模式配置:

@ShardingSphereTransactionType(TransactionType.SAGA) @SagaStart(timeoutSeconds = 300) public void createOrder(Order order) { // 正向操作 orderService.create(order); inventoryService.reduce(order.getItemId(), order.getCount()); // 补偿操作定义 @Compensate public void compensateCreate(Order order) { orderService.delete(order.getId()); inventoryService.increase(order.getItemId(), order.getCount()); } } 

六、实战案例

6.1 电商订单分库分表

场景特点: - 订单量日均10万+ - 需要按用户维度查询 - 历史订单需要归档

分片方案

spring: shardingsphere: sharding: tables: t_order: actual-data-nodes: ds$->{0..3}.t_order_$->{0..15} database-strategy: inline: sharding-column: user_id algorithm-expression: ds$->{user_id % 4} table-strategy: standard: sharding-column: order_time precise-algorithm-class-name: com.example.OrderTimePreciseShardingAlgorithm range-algorithm-class-name: com.example.OrderTimeRangeShardingAlgorithm 

6.2 多租户SAAS系统

场景特点: - 租户数量超过1000+ - 需要严格数据隔离 - 支持自定义租户分片策略

解决方案

public class TenantShardingAlgorithm implements PreciseShardingAlgorithm<String> { @Override public String doSharding(Collection<String> availableTargetNames, PreciseShardingValue<String> shardingValue) { // 根据租户ID哈希分片 int hash = Math.abs(shardingValue.getValue().hashCode()); int index = hash % availableTargetNames.size(); return new ArrayList<>(availableTargetNames).get(index); } } 

6.3 物联网时序数据

特殊需求: - 时间序列数据 - 需要定期自动创建新表 - 支持冷热数据分离

动态分片方案

public class TimeSeriesShardingAlgorithm implements PreciseShardingAlgorithm<Date> { private static final DateTimeFormatter TABLE_FORMAT = DateTimeFormatter.ofPattern("yyyy_MM"); @Override public String doSharding(Collection<String> availableTargetNames, PreciseShardingValue<Date> shardingValue) { LocalDate date = shardingValue.getValue().toInstant() .atZone(ZoneId.systemDefault()).toLocalDate(); String tableSuffix = date.format(TABLE_FORMAT); return availableTargetNames.stream() .filter(each -> each.endsWith(tableSuffix)) .findFirst() .orElseThrow(() -> new IllegalArgumentException("No table for date " + date)); } } 

七、性能优化

7.1 路由优化

最佳实践: 1. 避免全库全表扫描:

-- 错误写法(导致广播路由) SELECT * FROM t_order WHERE status = 1; -- 正确写法(带上分片键) SELECT * FROM t_order WHERE user_id = 123 AND status = 1; 
  1. 索引优化建议:
-- 分片键必须包含在索引中 ALTER TABLE t_order ADD INDEX idx_user_status (user_id, status); 

7.2 合并执行优化

配置参数调优:

spring: shardingsphere: props: max.connections.size.per.query: 5 # 每个查询最大连接数 executor.size: 20 # 执行线程池大小 kernel.executor.size: 20 # 内核线程池大小 

7.3 连接池配置

HikariCP优化建议: “`yaml spring: shardingsphere: datasource: ds0: hikari: maximum-pool-size:

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI