ShardingSphere-jdbc 5.5.0 + Spring Boot 分库分表读写分离配置实战
ShardingSphere-jdbc 5.5.0 Spring Boot 基础配置实战先说重点这个配置我做过多遍每次从旧版本升级到5.5.0都要踩一遍配置结构变化的坑。ShardingSphere 5.x 和 4.x 的配置方式完全不是一回事如果你是从 4.x 时代过来的会发现原来的spring.shardingsphere.datasource.names这类前缀全部失效5.5.0 直接走独立的application-shardingsphere.yaml或者放在 Spring Boot 配置里的shardingsphere.rules结构。如果到了这一步还按照老文档抄启动大概率直接报错。这篇文章面向的是需要快速上手的人你的服务已经跑着 Spring Boot 2.7 或 3.x现在需要接入分库分表不想被各种网上的碎片化文档折磨。我会把 5.5.0 版本的基础配置完整拆开从依赖引入、数据源配置、分片规则、分布式主键到常用的读写分离配置再到实际使用中的排查思路整个过程照着走一遍基本就能跑通。1. 版本选型与环境准备ShardingSphere-jdbc 本质上就是一个对 javax.sql.DataSource 的增强实现。它不改变你业务代码里的 JDBC 调用方式也不要求你必须用某个 ORM 框架MyBatis、MyBatis-Plus、Hibernate、JdbcTemplate 都能无缝对接。这意味着你的项目改造工作量集中在配置层而不是代码层这也是它相比其他分库分表方案最大的优势。1.1 依赖引入与版本对应关系5.5.0 这个版本比较特殊它同时兼顾了 Spring Boot 2.x 和 3.x 的生态。但这里有个关键细节Spring Boot 3.x 基于 Jakarta EE而 Spring Boot 2.x 使用的还是 javax。dependency groupIdorg.apache.shardingsphere/groupId artifactIdshardingsphere-jdbc-core/artifactId version5.5.0/version /dependency如果不引入shardingsphere-jdbc-core而只引入 starter在 Spring Boot 3.x 环境中会面临自动配置类无法加载的问题。从 5.4.0 开始官方对 Spring Boot 3 的支持已经比较完整但为了稳妥我建议核心包和 starter 一起引入。dependency groupIdorg.apache.shardingsphere/groupId artifactIdshardingsphere-jdbc-core/artifactId version5.5.0/version /dependency dependency groupIdorg.apache.shardingsphere/groupId artifactIdshardingsphere-jdbc-spring-boot-starter/artifactId version5.5.0/version /dependency如果你的项目还在用 Spring Boot 2.3 或更早版本那就不要把 5.5.0 硬塞进去挑 5.2.x 或者 5.3.x 反而更省事。版本匹配是一个组合问题不是越新越好。我用 5.5.0 搭配 Spring Boot 2.7.18 做了长时间的稳定性验证没有发现明显的兼容性问题这个组合比较推荐。注意不要同时引入shardingsphere-jdbc-spring-boot-starter和其他数据源 starter如druid-spring-boot-starter而不做排除处理。Starter 之间会自动竞争 DataSource Bean极容易造成路由失效或启动循环依赖。1.2 压测选型什么场景下你需要它在开始配之前先判断你的项目是否真的需要引入分库分表组件。我见过不少团队业务量连单库单表都没跑满就急急忙忙引入了分库分表结果事务从本地事务升级成了分布式事务性能反而下降了。ShardingSphere-jdbc 的核心价值体现在两个场景单表数据量超过千万级索引深了写入和查询都开始出现明显的延迟。业务有明显的分片维度比如订单按用户 ID 分片、日志按时间分片、消息按业务线分片。如果你的场景不属于这两类那建议先做其他优化比如索引优化、读写分离、缓存降级。分库分表解决的是数据容量和并发写入瓶颈不是慢查询的万能药。另外5.5.0 的代码已经在内核层做了很多优化比如对 SQL 解析阶段的缓存机制做了增强在相同配置下解析耗时相比 5.2.x 降低了约 30%。但对于那种只查询一天数据且很少跨库 join 的报表类系统单库单表加索引可能已经够了没必要增加运维复杂度。2. 核心配置文件拆解从数据源到规则5.5.0 的配置模型非常清晰由dataSources数据源、rules规则、props属性三段组成。三段缺一不可而且规则的类型和顺序是有讲究的。下面我给出一个包含了分库分表、读写分离、分布式主键的完整最小配置后面再逐步拆开讲。2.1 一个可以直接跑通的基础配置spring: shardingsphere: enabled: true datasource: names: ds-master-0,ds-master-0-slave-0,ds-master-1,ds-master-1-slave-0 ds-master-0: type: com.zaxxer.hikari.HikariDataSource driver-class-name: com.mysql.cj.jdbc.Driver jdbc-url: jdbc:mysql://172.20.10.3:3306/order_db_0?useSSLfalseserverTimezoneAsia/Shanghai username: root password: root123 ds-master-0-slave-0: type: com.zaxxer.hikari.HikariDataSource driver-class-name: com.mysql.cj.jdbc.Driver jdbc-url: jdbc:mysql://172.20.10.4:3306/order_db_0?useSSLfalseserverTimezoneAsia/Shanghai username: root password: root123 ds-master-1: type: com.zaxxer.hikari.HikariDataSource driver-class-name: com.mysql.cj.jdbc.Driver jdbc-url: jdbc:mysql://172.20.10.3:3306/order_db_1?useSSLfalseserverTimezoneAsia/Shanghai username: root password: root123 ds-master-1-slave-0: type: com.zaxxer.hikari.HikariDataSource driver-class-name: com.mysql.cj.jdbc.Driver jdbc-url: jdbc:mysql://172.20.10.4:3306/order_db_1?useSSLfalseserverTimezoneAsia/Shanghai username: root password: root123 rules: sharding: binding-tables: - t_order,t_order_item broadcast-tables: - t_dict default-database-strategy: standard: sharding-column: tenant_id sharding-algorithm-name: database-inline tables: t_order: actual-data-nodes: ds-$-{0..1}.t_order_$-{0..1} database-strategy: standard: sharding-column: user_id sharding-algorithm-name: database-inline table-strategy: standard: sharding-column: user_id sharding-algorithm-name: table-inline keyGenerateStrategy: column: id key-generator-name: snowflake t_order_item: actual-data-nodes: ds-$-{0..1}.t_order_item_$-{0..1} database-strategy: standard: sharding-column: user_id sharding-algorithm-name: database-inline table-strategy: standard: sharding-column: user_id sharding-algorithm-name: table-inline keyGenerateStrategy: column: id key-generator-name: snowflake key-generators: snowflake: type: SNOWFLAKE props: worker-id: 1 sharding-algorithms: database-inline: type: INLINE props: algorithm-expression: ds-$-{user_id % 2} allow-range-query-with-inline-sharding: true table-inline: type: INLINE props: algorithm-expression: t_order_$-{user_id % 2} allow-range-query-with-inline-sharding: true readwrite-split: >algorithm-expression: ds-$-{user_id % 2}别小看这一点我当年排查这个问题的姿势是每个表的数据都在但分布不对一半数据路由到了一个不存在的逻辑库名上。后来看解析日志才发现是占位符冲突。还有一个容易被忽略的参数allow-range-query-with-inline-sharding。它的含义是是否允许在分片键上执行范围查询。默认值是 false也就是说你会遇到一条 SQL 查询WHERE user_id BETWEEN 1 AND 100直接被拒绝执行或路由结果报错。如果需要范围内查询需要显式设置这个参数为 true但注意 INLINE 分片不支持范围路由优化开启后依然会全库全表扫描性能上要有预期。3.2 分片策略选型默认策略与表策略的关系配置中有两处策略default-database-strategy默认库策略和tables下的database-strategy表级库策略。它们的优先级是表级策略 默认策略。如果某个表没有单独配置库策略就用默认配置如果配置了就用表级的。我用这个机制把大多数表分片的相同规则收敛到默认策略集中管理同时保留个别表走独立策略的灵活性。分片策略有两种standard标准策略和complex复合策略。标准策略仅支持单分片键的 SQL 路由复合策略支持多个分片键参与路由计算。如果将来有按user_id time双键分片的需求要在这里选择complex并配置sharding-algorithm-name指向COMPLEX_INLINE或自定义类实现。注意标准策略不支持跨分片键的关联查询若强制执行单 SQL 跨多分片查询ShardingSphere 会执行全路由full-route扫描所有分片结果是数据对但性能会明显下降需要提前做好评估。3.3 分片键选择的核心原则分片键决定了数据分布均匀性和查询命中率。选择分片键的核心原则有两层第一层尽量选业务天然分布均匀的字段比如用户 ID。不要选状态字段只有几个值或时间字段如果业务有热点时段会产生数据倾斜。第二层分片键必须能覆盖主要查询条件。如果还有大量查询不是按分片键走的要么补充二级索引表可以用广播表实现要么考虑用复合分片键去覆盖高频查询。如果经常做SELECT * FROM t_order WHERE order_no xxx而分片键是user_id那这个查询只能全路由效率极低。解决办法是额外建一张t_order_no_mapping表把order_no和user_id的映射关系存下来先查映射表拿到user_id再路由实际订单表。3.4 自定义分片算法分片算法支持嵌入 Java 代码来定义。如果内置的 INLINE 满足不了复杂业务比如按月份分表、按地域分片可以在 Java 类中实现StandardShardingAlgorithmT接口然后在 YAML 中通过type: CLASS_BASED注册。public class UserIdMonthShardingAlgorithm implements StandardShardingAlgorithmString { Override public String doSharding(final CollectionString availableTargetNames, final PreciseShardingValueString shardingValue) { String value shardingValue.getValue(); String target t_order_ value.substring(0, 6); if (availableTargetNames.contains(target)) { return target; } throw new UnsupportedOperationException(路由目标不存在: target); } Override public CollectionString doSharding(final CollectionString availableTargetNames, final RangeShardingValueString shardingValue) { CollectionString result new LinkedList(); for (String target : availableTargetNames) { result.add(target); } return result; } Override public void init() { } Override public String getType() { return USER_ID_MONTH; } }YAML 中注册sharding-algorithms: user-id-month: type: CLASS_BASED props: strategy: standard algorithmClassName: com.example.sharding.UserIdMonthShardingAlgorithm这里有两个注意点getType()返回值 YAML 中对应的 type 是什么就填什么。我这里返回的是USER_ID_MONTHYAML 里的type就写CLASS_BASED固定值然后通过algorithmClassName找到你的类。范围查询的doSharding不要偷懒返回空集否则BETWEEN查询会直接报错。最稳妥的实现是返回所有可行目标交给 ShardingSphere 在内部进行归并。4. 分布式主键与绑定表、广播表配置分片之后自增主键的全局唯一性保证就不能再依赖数据库自增了。ShardingSphere 提供了分布式主键生成器默认是雪花算法SNOWFLAKE实现。4.1 雪花算法的 worker-id 与时钟回拨问题雪花算法生成的 ID 由时间戳、工作节点、序列号三部分组成。在 5.5.0 中worker-id默认值是从配置中心拉取或者使用本机 IP 取模计算但多个应用实例如果没有确切指定可能会生成相同的 workerId导致 ID 冲突。实践上我会给每个实例显式配置key-generators: snowflake: type: SNOWFLAKE props: worker-id: 1 max-tolerate-time-difference-milliseconds: 10max-tolerate-time-difference-milliseconds这个参数用于容忍主机之间的时钟偏移。如果超过这个阈值生成时会抛异常而不是生成错误 ID这对订单类、支付类系统的可追溯性非常重要。注意主键字段在数据库里的类型必须是 BIGINT。用 varchar 存雪花 ID 也可以但索引和存储效率会降低。生成策略在 YAML 中通过keyGenerateStrategy指定后应用层不需要改动ShardingSphere 会自动填充主键字段。4.2 绑定表的配置意义与 join 性能优化绑定表的概念逻辑上具有相同分片规则的一组表比如t_order和t_order_item都按user_id分片且分片数一致。如果不配置绑定关系当执行两表 join 时会先做笛卡尔积路由2 个分片库 × 2 个分片表 4 个分组 SQL全部并行执行再在内存中归并性能很低。配置绑定表后ShardingSphere 会保证同一user_id的数据在t_order和t_order_item中落到相同的库和表join 时路由到同库同分片只需执行 2 条 SQL。绑定表配置本身没有任何副作用只要分片规则确实一致建议直接把所有有 join 关系的表全部绑上。4.3 广播表的使用边界广播表对应每个库中都存在的相同结构小表典型代表是字典表、配置表。它会把写操作广播到所有分片库查询时从任意一个分片拉取。但广播表不是免费的每次写入都会放大到所有分片如果字典表经常更新且数据量大写放大效应会很严重。跨库事务会存在一致性问题需要额外的补偿机制。所以广播表只适合低频写入、数据量小的场景。常见做法是字典表在应用启动时加载到本地缓存Caffeine数据库只作为持久化写入频率极低这样广播表的写放大影响可以忽略。4.4 分布式 ID 生成器在实际使用中的几个问题雪花 ID 看起来只是主键但生产上碰过几个很有意思的问题列出来供参考长整型精度溢出尤其是前端 JavaScript 无法精确表示 2^53 以上的整数。后端插入正常前端拿到 ID 后会出现末几位全部是 0。解决方式是接口返回时转成字符串。用雪花 ID 做分页排序时因为 ID 不是连续的页面上依赖 ID 作为游标做增量查询是可行的但注意 ID 的大小关系只反映创建时刻的时间顺序。某些 ORM 框架的 ID 回填机制和 ShardingSphere 的 keyGenerateStrategy 有冲突。典型表现你配置了主键生成策略但业务代码里手动 set 了 IDShardingSphere 会忽略你的 set 值直接用雪花生成导致数据错乱。解决方案是只要用了 keyGenerateStrategy业务代码一律不要主动设置主键。5. 读写分离与分片规则的联动配置5.5.0 的读写分离规则在上一版基础上有一些变化需要注意优先级readwrite-split规则建立在物理数据源之上sharding规则再建立在readwrite-split的逻辑数据源之上。换言之配置的层级是物理数据源 → 读写分离逻辑数据源 → 分片逻辑数据源。5.1 读写分离的数据源命名规范在上面的配置中可以看到我把物理库定义为ds-master-0、ds-master-0-slave-0、ds-master-1、ds-master-1-slave-0然后定义了两个 readwrite-split 逻辑数据源order_readwrite_0和order_readwrite_1。如果此时分片规则里的actual-data-nodes写的是ds-$-{0..1}.t_order_$-{0..1}那路由处理时会优先找 readwrite-split 逻辑数据源而不是最底层的物理数据源。命名上一定要保持逻辑清晰不要出现像ds-master-0既是物理数据源又被用于逻辑引用这种混乱。推荐命名规则物理写库w0、w1物理读库r0-0、r1-0读写分离逻辑库rw0、rw1分片配置引用的就是rw0、rw1这样一来配置里看到actual-data-nodes: rw$-{0..1}.t_order_$-{0..1}一眼就知道走的是读写分离逻辑。5.2 同库同表场景的数据一致性风险提示读写分离的数据一致性由主从复制保证ShardingSphere 本身不参与复制链路。如果主从延迟严重读写分离后立刻读从库会读到旧数据。有两个应对思路强制路由主库。ShardingSphere 提供了 Hint 机制可以设置HintManager.getInstance().setWriteRouteOnly()但只适合特定读多写少的场景不要全局开启。配置主从延迟阈值。5.5.0 支持readwrite-split的负载均衡算法可以选择ROUND_ROBIN或RANDOM但无法做到基于延迟的动态感知。高一致性要求的查询建议还是走主库。5.3 多从库负载均衡算法配置当读数据源配置了多个时可以指定负载均衡策略readwrite-split: >

相关新闻

拆解kms.zip:内网KMS批量激活与自动化运维全攻略

拆解kms.zip:内网KMS批量激活与自动化运维全攻略

简介:这是一套面向网页实时通信开发者的KMS技术学习资源,压缩包内包含两个文件,分别是一个网页文件和一个脚本文件,整体大小仅约1KB,轻量易用。资料以《KMS技术详解:网页实时通信实现与应用》为背景&#x…

2026/10/17 10:56:20 阅读更多 →
Redis实战面试题精选:从数据结构到分布式锁的深度解析

Redis实战面试题精选:从数据结构到分布式锁的深度解析

最近帮团队做技术摸底的时候,把一批候选人挂了之后,自己反而被一个问题问住了:市面上能搜到的Redis面试题多到能堆成小山,但真正遇到线上问题的时候,能用上的几乎没有。后来我把这几年面试中反复出现的高频问题、以及自…

2026/10/17 12:13:02 阅读更多 →
大模型网关有哪些?2026国内外12款主流产品解析:托管、开源、私有化三种落地方式

大模型网关有哪些?2026国内外12款主流产品解析:托管、开源、私有化三种落地方式

产品信息为公开资料整理,截至 2026 年 10 月;文中用量与成本为示例估算,不代表任何模型的实际价格。排列不构成排名。本文是《AI 网关五大品类全景图》中"大模型网关"一类的展开篇。大模型的单价每年都在降,企业的 AI 账…

2026/10/16 8:50:52 阅读更多 →

最新新闻

qModel v1.4.2模型版本管理实战:创建、对比、切换与回滚全攻略

qModel v1.4.2模型版本管理实战:创建、对比、切换与回滚全攻略

做算法工程师这几年,我一直有一个执念:模型版本管理这件事,绝不能等到线上出事了才想起来补课。代码有Git管理,数据有数据仓库,偏偏模型文件常常散落在各个训练机的磁盘、网盘甚至U盘里,谁训的、用的什么数…

2026/10/17 12:12:42 阅读更多 →
AI应用编排实战:智能表单、流程编排与插件开发快速上手

AI应用编排实战:智能表单、流程编排与插件开发快速上手

最近一段时间,我大部分精力都泡在一个叫ModelEngine的AI应用编排平台上。说真的,第一次看到这个工具时,我第一反应是“又一个低代码平台”。但实际用了一个月、给某电商客户落地了一套售后反馈分析应用之后,我改变了看法。它真正解…

2026/10/17 12:12:42 阅读更多 →
Dify搭建搜索与文档阅读智能体:工具调用、提示词与避坑全指南

Dify搭建搜索与文档阅读智能体:工具调用、提示词与避坑全指南

我最近在Dify上搭了一个既能联网搜索、又能读本地文档的智能体,整个过程比我预想的顺利,但没有哪一步是"光靠直觉就能成"的。比如工具描述写得不清楚,模型就死活不调搜索接口;比如文档上传方式选错了,几十页…

2026/10/17 12:12:42 阅读更多 →
MCP与LangGraph实战:把AI Agent脚本重构成生产级系统

MCP与LangGraph实战:把AI Agent脚本重构成生产级系统

做 AI 应用最难受的一个时刻,是脚本里的 demo 跑得风生水起,一推上生产就四处漏风。过去一年我接手好几套类似系统,骨架都差不多:一个 Python 脚本,把用户输入塞给大模型,模型说要调工具就 if-else 判断一下…

2026/10/17 12:12:42 阅读更多 →
Trezor硬件钱包取证:加密备份提取与压缩包解析实战

Trezor硬件钱包取证:加密备份提取与压缩包解析实战

简介:这份PDF文档聚焦硬件钱包数字取证这一细分领域,面向CTF-Misc方向的学习者、数字取证人员与安全研究人员,系统讲解如何从Trezor设备中提取加密备份压缩包。内容从Trezor硬件钱包的工作原理、存储格式与备份策略讲起,逐步深入到…

2026/10/17 12:12:42 阅读更多 →
artcraft:从创意到成品的执行方法论与流程控制

artcraft:从创意到成品的执行方法论与流程控制

1. 从“artcraft”这个名字说起:它到底想解决什么问题 第一次看到“artcraft”这个词,我脑子里蹦出来的不是某个具体工具,而是一种很朴素的组合感——art(艺术、审美、表达)加上 craft(手艺、工艺、打磨&am…

2026/10/17 12:11:42 阅读更多 →

日新闻

DeepSeek选型与部署:V3/R1、Ollama、API全攻略

DeepSeek选型与部署:V3/R1、Ollama、API全攻略

简介:《DeepSeek使用方法.pdf》是一份面向DeepSeek入门及进阶用户的完整使用指南,重点围绕V3与R1两款模型的能力差异与适用场景展开,帮助读者根据任务类型与成本选择合适的模型。资源共1个PDF文件,压缩包大小约311KB,篇…

2026/10/17 0:00:25 阅读更多 →
200+Deepseek润色指令拆解:从底层原理到场景落地的完整指南

200+Deepseek润色指令拆解:从底层原理到场景落地的完整指南

简介:这是一份聚焦DeepSeek提示词优化的《200Deepseek润色指令》PDF文档,共收录两百余条可直接套用的润色指令,涵盖语法修正、风格统一、逻辑梳理、表达精炼等维度,并针对商务写作、学术论文、广告文案等场景给出差异化建议。文档…

2026/10/17 0:00:25 阅读更多 →
OpenCV轮廓法物体计数系统:轻量、可控、可落地的工业级实现

OpenCV轮廓法物体计数系统:轻量、可控、可落地的工业级实现

简介:本资源是一份基于OpenCV的本科课程设计完整报告,面向计算机视觉初学者、图像处理学习者及高校通信/信息类专业学生,解决物体智能计数与检测结果结构化记录的实际问题。项目覆盖图像预处理、轮廓检测、边界框绘制、轨迹栏交互式参数调节、…

2026/10/17 0:00:25 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/16 21:35:51 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/17 1:44:59 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/16 15:04:24 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/16 21:54:38 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/16 3:49:43 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/16 14:23:36 阅读更多 →