分库分表技术栈讲解-Sharding-JDBC
大家好,我是工藤学编程 🦉 | 一个正在努力学习的小博主,期待你的关注 |
---|---|
实战代码系列最新文章😉 | C++实现图书管理系统(Qt C++ GUI界面版) |
SpringBoot实战系列🐷 | 【SpringBoot实战系列】Sharding-Jdbc实现分库分表到分布式ID生成器Snowflake自定义wrokId实战 |
环境搭建大集合 | 环境搭建大集合(持续更新) |
分库分表 | 分库分表之策略 |
前情摘要:
1、数据库性能优化
2、分库分表之优缺点分析
3、分库分表之数据库分片分类
4、分库分表之策略
本文章目录
- (一)业界常见分库分表中间件详解
- Cobar(已淘汰)
- TDDL
- Mycat
- ShardingSphere 下的Sharding-JDBC
- Mycat与ShardingJdbc的区别
- 一、中间件分类与核心架构对比
- 1. 客户端模式(Client Side)
- 2. 代理模式(Proxy Side)
- 3. Sidecar模式
- 二、主流中间件深度对比
- 三、Mycat与Sharding-JDBC的深度对比
- 1. 设计理念差异
- 2. 关键功能对比
- 四、选型决策树
- (二) 分库分表与Sharding-JDBC常见概念术语详解
- 数据节点(Node)
- 真实表
- 逻辑表
- 绑定表
- 广播表
- 对比
- 分片基础概念
- 分片策略详解
- 1. 行表达式分片策略 (InlineShardingStrategy)
- 2. 标准分片策略 (StandardShardingStrategy)
- 3. 复合分片策略 (ComplexShardingStrategy)
- 4. Hint分片策略 (HintShardingStrategy)
- 5. 不分片策略 (NoneShardingStrategy)
- 分片算法对比表
- 自定义分片策略的优缺点
- 分片算法选择建议
(一)业界常见分库分表中间件详解
Cobar(已淘汰)
- 基本情况:曾经是较为流行的分库分表中间件,但目前已停止维护和更新,在实际项目中已很少使用。
- 淘汰原因:缺乏持续的技术支持,无法满足现代业务对中间件的功能和性能需求。
TDDL
- 背景:由淘宝根据自身业务特点开发,是 Taobao Distributed Data Layer 的缩写。
- 技术特点:
- 基于JDBC规范设计,没有独立的server端,以client-jar的形式存在,引入项目即可使用。
- 主要在阿里内部使用,开源功能较少。
- 适用场景:适合阿里系内部具有特定业务需求的场景,对于外部普通项目适用性有限。
Mycat
- 官网地址:http://www.mycat.org.cn/
- 技术架构:
- 采用Java语言编写,是基于MySQL数据库网络协议的开源中间件,其前身为Cobar。
- 遵守MySQL原生协议,是跨语言、跨平台、跨数据库的通用中间件代理。
- 基于Proxy模式,复写了MySQL协议,将Mycat Server伪装成一个MySQL数据库,与ShardingSphere下的Sharding-Proxy作用类似,需要单独部署。
- 核心功能:
- 支持SQL92标准,兼容MySQL、Oracle、DB2等多种数据库的常见SQL语法。
- 具备基于心跳的自动故障切换功能,支持读写分离,以及MySQL主从和Galera cluster集群。
- 支持数据的多片自动路由与聚合,包括sum、count、max等常用聚合函数,还支持跨库分页。
- 支持分布式事务(包括弱XA和XA分布式事务),以及全局序列号生成,解决分布式环境下的主键生成问题。
- 优缺点:
- 优点:代码无侵入性,客户端的所有JDBC请求只需交给MyCat,由其转发到具体的真实服务器。
- 缺点:由于中间增加了一层代理,效率相对偏低。
ShardingSphere 下的Sharding-JDBC
- 官网地址:https://shardingsphere.apache.org/
- 技术体系:
- Apache ShardingSphere是一套开源的分布式数据库中间件解决方案生态圈,由Sharding-JDBC、Sharding-Proxy和Sharding Sidecar三个独立产品组合而成。
- Sharding-JDBC基于JDBC驱动,不需要额外的proxy,支持任意实现JDBC规范的数据库。
- 它以jar包形式提供服务,客户端直连数据库,无需额外部署和依赖,可理解为加强版的JDBC驱动,兼容JDBC和各类ORM框架。
- 核心功能:
- 提供数据分片功能,实现数据库的水平扩展,提升计算和存储能力。
- 支持读写分离,能够基于SQL语义理解和对底层数据库拓扑的感知,实现读访问的负载均衡。
- 具备分布式事务能力,通过基于XA和BASE事务的混合引擎,在独立数据库之上提供分布式事务支持。
- 提供数据加密与脱敏解决方案,保障数据安全。
- 支持多数据库,包括MySQL、PostgreSQL、SQL Server、Oracle等SQL-92兼容数据库。
- 优缺点:
- 优点:基于JDBC接口扩展,性能较高。
- 缺点:存在一定的代码侵入性,需要在本地应用层重写JDBC原生方法来实现数据库分片。
Mycat与ShardingJdbc的区别
- 相同点:两者的设计理念相同,主流程均为SQL解析→SQL路由→SQL改写→结果归并。
- 不同点:
- 架构模式:Sharding-JDBC是基于JDBC驱动的客户端模式,而Mycat是基于Proxy的服务器端模式。
- 部署方式:Sharding-JDBC以jar包形式集成在应用中,无需额外部署;Mycat需要单独部署服务器。
- 代码侵入性:Sharding-JDBC存在代码侵入性,Mycat则无代码侵入。
- 性能表现:Sharding-JDBC由于直接与数据库连接,性能相对较高;Mycat经过代理转发,性能会有一定损耗。# 业界主流分库分表中间件对比与选型指南
一、中间件分类与核心架构对比
1. 客户端模式(Client Side)
- 典型代表:Sharding-JDBC、TDDL
- 架构特点:
- 以Jar包形式集成在应用内部,直接访问数据库;
- 无需独立部署,逻辑嵌入应用层。
- 优势:
- 无额外网络开销,性能最优(通常比Proxy模式高10%-20%);
- 部署简单,适合微服务架构。
- 局限:
- 与应用强绑定,升级需重启服务;
- 分片逻辑分散在多个应用中,管理复杂度高。
2. 代理模式(Proxy Side)
- 典型代表:Mycat、Sharding-Proxy、Cobar
- 架构特点:
- 独立部署为中间层,客户端通过标准协议(如MySQL协议)连接;
- 对应用透明,可视为“虚拟数据库”。
- 优势:
- 应用无代码侵入,支持异构语言(如Java、Python、Go);
- 集中管理分片规则,便于运维。
- 局限:
- 额外网络跳数,性能略低;
- 需独立维护中间件集群,高可用复杂度提升。
3. Sidecar模式
- 典型代表:Sharding-Sidecar(规划中)
- 架构特点:
- 以容器形式与应用同节点部署(如Kubernetes中的Pod);
- 继承Client模式性能优势,同时解耦应用与中间件。
- 优势:
- 无代码侵入,支持云原生架构;
- 资源隔离,不影响应用性能。
- 局限:
- 依赖容器编排平台,部署复杂度高;
- 社区成熟度较低。
二、主流中间件深度对比
特性 | Sharding-JDBC | Mycat | Sharding-Proxy | TDDL |
---|---|---|---|---|
所属生态 | Apache ShardingSphere | 独立开源项目 | Apache ShardingSphere | 阿里云(内部为主) |
模式 | Client | Proxy | Proxy | Client |
数据库支持 | 任意JDBC兼容数据库(MySQL、PostgreSQL等) | MySQL、Oracle、SQL Server等 | 同Sharding-JDBC | 主要支持MySQL |
分片规则 | Java代码配置(YAML/注解) | XML配置文件 | YAML配置文件 | 自定义SPI接口 |
性能(TPS) | 高(无代理开销) | 中(单节点约为Sharding-JDBC的70%-80%) | 中(接近Mycat) | 高(阿里内部优化) |
代码侵入性 | 高(需集成依赖并修改配置) | 无(仅需修改连接URL) | 无(同Mycat) | 中(需集成TDDL客户端) |
分布式事务支持 | 支持XA、Seata、TCC等 | 支持XA、柔性事务 | 同Sharding-JDBC | 阿里内部事务框架 |
读写分离 | 支持 | 支持 | 支持 | 支持 |
分库分表复杂度 | 高(需自行实现复杂规则) | 低(配置文件更友好) | 高(同Sharding-JDBC) | 中(阿里内部封装) |
社区活跃度 | 高(Apache顶级项目) | 中(核心团队维护) | 高(同Sharding-JDBC) | 低(仅内部更新) |
适用场景 | 微服务架构、Java技术栈 | 异构语言、遗留系统升级 | 云原生架构、统一管控 | 阿里系应用 |
三、Mycat与Sharding-JDBC的深度对比
1. 设计理念差异
- Mycat:
- 定位为“数据库代理层”,强调对应用透明,适合“无代码修改”需求;
- 核心优势在于对复杂SQL(如跨库JOIN)的优化支持。
- Sharding-JDBC:
- 定位为“增强型JDBC驱动”,强调性能与灵活性,适合“可接受代码侵入”的场景;
- 核心优势在于与Spring Boot/Cloud的深度集成(如自动配置、SPI扩展)。
2. 关键功能对比
功能点 | Mycat | Sharding-JDBC |
---|---|---|
SQL解析能力 | 强(支持复杂SQL改写) | 中(简单SQL优先,复杂SQL需自定义) |
分布式事务 | 支持XA与柔性事务(需依赖数据库) | 支持Seata、TCC等多种模式 |
动态扩容 | 需手动配置与数据迁移 | 支持弹性扩容(如通过ShardingSphere-弹性伸缩模块) |
监控告警 | 内置监控页面,支持Prometheus | 集成Micrometer,支持自定义 |
四、选型决策树
-
优先选择Sharding-JDBC的场景:
- 微服务架构,追求极致性能;
- 技术栈为Java,且可接受代码侵入;
- 需要与Spring生态深度集成(如Spring Boot自动配置)。
-
优先选择Mycat的场景:
- 异构语言环境(如Java、Python混合);
- 遗留系统改造,要求无代码侵入;
- 需要复杂SQL支持(如跨库分页、子查询)。
-
优先选择Sharding-Proxy的场景:
- 云原生架构,需统一管控中间件;
- 多租户环境,需资源隔离;
- 需支持非Java技术栈。
-
优先选择TDDL的场景:
- 已在阿里云环境,且业务场景与阿里内部类似;
- 需依赖阿里的分布式事务与高可用方案。
(二) 分库分表与Sharding-JDBC常见概念术语详解
数据节点(Node)
定义:数据分片的最小物理存储单元,由数据源名称(数据库实例)和数据表组成,用于定位数据存储位置。
结构:数据源名称.物理表名
示例:
ds_0.product_order_0
表示数据源ds_0
中的product_order_0
表ds_1.user_info_1
表示数据源ds_1
中的user_info_1
表
作用:Sharding-JDBC 通过数据节点映射逻辑表与物理表的关系,实现分片查询路由。
真实表
定义:数据库中实际存储数据的物理表,需按照分片规则提前创建。
命名规范:通常采用 逻辑表名_分片后缀
的形式(如 order_0
, order_1
)。
示例:
- 水平分表后的订单表:
product_order_0
,product_order_1
,product_order_2
- 垂直分库后的用户表:
ds_user.user_info
,ds_order.user_address
注意事项:
- 真实表的字段需与逻辑表保持一致
- 分片键(如
order_id
)必须包含在真实表结构中
逻辑表
定义:用户视角的虚拟表,代表一组分片后的物理表的逻辑集合,屏蔽底层分片细节。
使用方式:
- SQL 中直接使用逻辑表名(如
SELECT * FROM product_order
) - 通过 Sharding-JDBC 配置逻辑表与真实表的映射关系
优势:
- 应用层无需感知分片细节,保持 SQL 书写习惯
- 支持平滑扩缩容(调整分片规则时无需修改业务 SQL)
绑定表
定义:分片规则一致的主表和子表,通过相同分片键进行分片,确保数据在物理上处于同一分片。
核心特性:
- 分片键一致性:主表与子表必须使用相同字段作为分片键(如
order_id
) - 关联查询优化:避免跨分片笛卡尔积,提升 JOIN 性能
广播表
定义:在所有分片数据源中完全复制的表,用于存储全局共享数据(如字典、配置)。
特性:
- 数据一致性:所有分库中的广播表数据完全相同
- 自动同步:插入/更新操作会自动同步到所有分库
- 查询优化:跨库 JOIN 无需分片路由
适用场景:
- 数据量小(通常 < 10MB)且更新频率低
- 需与海量数据表频繁关联(如订单表 JOIN 支付类型字典)
注意事项:
- 避免存储大表(会导致数据冗余和同步开销)
- 仅支持单表更新,不支持跨广播表事务
对比
概念 | 数据分布特点 | 适用场景 | 性能优势 |
---|---|---|---|
绑定表 | 分片规则相同,数据同库同表 | 主从表高频 JOIN 查询 | 避免跨分片关联 |
广播表 | 全部分片完全复制 | 小表与大表高频关联 | 本地 JOIN,无需路由 |
普通分片表 | 按规则分散存储 | 数据量巨大的水平拆分场景 | 数据均匀分布,负载均衡 |
#(三) 分库分表与Sharding-JDBC常见分片算法详解
分片基础概念
分片键 (Partition Key)
- 定义:用于决定数据分片位置的数据库字段,是水平分库/分表的核心依据。
- 单分片键:如
order_id
、user_id
- 多分片键:组合多个字段共同决定分片位置(如
user_id + order_date
)
分片策略:定义数据如何分布到多个节点,Sharding-JDBC提供多种内置策略。
分片策略详解
1. 行表达式分片策略 (InlineShardingStrategy)
特点:
- 仅支持单分片键
- 使用Groovy表达式定义分片规则
- 支持
=
和IN
操作符
适用场景:
- 简单取模分片(如按用户ID分库、订单ID分表)
- 无需自定义代码,快速实现分片
2. 标准分片策略 (StandardShardingStrategy)
特点:
- 仅支持单分片键
- 需实现两种分片算法:
- PreciseShardingAlgorithm(必选):处理
=
和IN
查询 - RangeShardingAlgorithm(可选):处理
BETWEEN AND
查询
- PreciseShardingAlgorithm(必选):处理
注意事项:
- 若未实现
RangeShardingAlgorithm
,BETWEEN AND
查询将触发全库表扫描
3. 复合分片策略 (ComplexShardingStrategy)
特点:
- 支持多分片键(如
user_id + order_time
) - 需自定义算法处理复杂分片逻辑
适用场景:
- 分片逻辑依赖多个字段组合(如按用户分库,按订单时间分表)
- 需支持多种查询条件(如按用户ID精确查询,按时间范围查询)
4. Hint分片策略 (HintShardingStrategy)
特点:
- 不依赖SQL中的分片键,通过编程方式手动指定分片
- 绕过SQL解析,性能优化场景
适用场景:
- SQL中不含分片键(如统计查询)
- 强制路由到特定分片(如数据修复)
5. 不分片策略 (NoneShardingStrategy)
特点:
- 不进行分片,所有数据存储在单一库表中
- 用于过渡阶段或无需分片的表
分片算法对比表
策略类型 | 分片键数量 | 支持操作符 | 自定义程度 | 适用场景 |
---|---|---|---|---|
InlineShardingStrategy | 单键 | =, IN | 低 | 简单取模分片 |
StandardSharding | 单键 | =, IN, BETWEEN AND | 中 | 需要处理范围查询 |
ComplexSharding | 多键 | 全部 | 高 | 复杂分片逻辑 |
HintSharding | 无 | 全部 | 高 | 强制路由或无分片键查询 |
NoneSharding | 无 | 全部 | 无 | 不分片的表 |
自定义分片策略的优缺点
优点:
- 灵活性高:可实现任意复杂的分片逻辑(如按地域、业务类型分片)
- 性能优化:针对特定查询模式定制分片规则
- 数据倾斜处理:通过自定义算法避免数据分布不均
缺点:
- 开发成本高:需编写和维护分片算法代码
- SQL兼容性风险:复杂查询可能触发全库表扫描
- 运维难度大:分片规则变更需同步更新算法代码
分片算法选择建议
- 优先使用 Inline 策略:满足简单取模需求,无需编码
- 范围查询较多时:使用 Standard 策略并实现 Range 算法
- 多分片键场景:使用 Complex 策略,注意控制复杂度
- 特殊路由需求:使用 Hint 策略(如批量数据导入)
- 分片逻辑复杂:权衡自定义分片与业务复杂度,避免过度设计
最佳实践:从简单策略开始,仅在必要时升级到更复杂的分片方案。