Sharding-JDBC读写分离与分库分表实战指南

发布时间:2026/9/10 5:11:29

Sharding-JDBC读写分离与分库分表实战指南 简介本资源是一份基于SpringBoot框架集成Sharding-JDBC实现读写分离与分库分表的完整实践工程面向Java后端开发者及数据库性能优化学习者解决高并发场景下单库瓶颈、读写压力不均与水平扩展难题。压缩包共14个文件含5个YAML配置文件定义数据源、分片规则与读写分离策略、4个Java类含Sharding配置类与核心业务逻辑、1个Maven XML依赖配置、1个Windows启动脚本mvnw.cmd、1个README说明文档等结构清晰、开箱即用总大小仅17KB轻量易导入。已有183人学习下载适合中初级开发者快速掌握Sharding-JDBC在SpringBoot中的标准接入流程。读者可直接复用配置模板、理解分片键设计逻辑、观察多数据源路由行为并通过项目目录组织厘清ShardingSphere与Spring生态的整合范式是数据库中间件落地的典型轻量级参考案例。1. 不是加个依赖就能跑通的分库分表Sharding-JDBC 的读写分离与分库分表必须直面连接池、事务边界和 SQL 兼容性三座大山很多团队在 Spring Boot 项目里引入sharding-jdbc-spring-boot-starter后第一反应是“终于不用自己手写路由逻辑了”结果一跑就报No available datasource或Can not find owner data source更常见的是明明配置了主从分离SELECT却总打到主库INSERT后立刻SELECT却查不到新数据——这不是 Sharding-JDBC 的 Bug而是它把数据库中间件的底层契约彻底暴露了出来它不接管连接不代理网络不重写协议只做 SQL 解析 逻辑路由 结果归并。这意味着你必须亲手对齐 JDBC 层的连接生命周期、事务传播行为、以及 MariaDB/MySQL 的主从同步延迟容忍度。本文聚焦真实生产环境中的最小可行路径用 Sharding-JDBC 5.3.2当前稳定版在单应用内实现「可验证的读写分离 按 user_id 分库分表」所有配置均通过application.yml声明式完成不写一行 Java 路由代码但每一步都标注 MariaDB 主从同步参数、HikariCP 连接池关键阈值、以及Transactional的作用域陷阱。2. 为什么选 Sharding-JDBC 而不是 MyCat 或 ProxySQL核心在于 JDBC 层透明与无状态路由能力2.1 Sharding-JDBC 的定位本质是“JDBC 增强驱动”不是独立中间件Sharding-JDBC 并非部署在应用和数据库之间的代理服务如 MyCat而是以 JDBC Driver 的形式嵌入应用进程。它拦截DataSource.getConnection()返回的ShardingSphereDataSource再将Statement.execute()的 SQL 字符串解析为抽象语法树AST根据分片规则决定路由到哪个物理数据源。这种设计带来三个硬约束零网络跳转SQL 执行路径仍是应用 → 数据库直连规避了代理层的网络延迟和单点故障事务强一致性本地事务Transactional可跨分片生效需满足 XA 或 Seata 配合而 MyCat 的分布式事务需额外协调无额外运维成本无需维护独立进程、端口、配置中心适合中小团队快速落地。提示Sharding-JDBC 5.x 已合并进 Apache ShardingSphere 生态但sharding-jdbc-spring-boot-starter仍作为轻量级 JDBC 模式独立维护与shardingsphere-jdbc-core-spring-boot-starter功能一致本文统一使用后者。2.2 读写分离与分库分表必须解耦设计先确保主从路由正确再叠加分片逻辑错误做法是直接配置sharding: rules:下的readwrite-splitting和sharding-algorithms一起启用。正确路径是分两阶段验证阶段一本节重点关闭分库分表仅启用读写分离用SELECT /* USE_SLAVE */ * FROM t_user强制走从库确认show processlist中连接来源为从库 IP阶段二在读写分离稳定后再加入分片规则避免问题叠加导致排查困难。2.2.1 MariaDB 主从同步参数必须显式对齐应用层预期Sharding-JDBC 的readwrite-splitting策略默认采用load_balancer_type: ROUND_ROBIN但若从库存在同步延迟ROUND_ROBIN可能将请求路由到尚未同步完的从库。因此必须在 MariaDB 侧配置半同步复制Semi-Sync Replication并设置rpl_semi_sync_master_wait_point AFTER_SYNC同时在应用侧强制要求主库写入后SELECT必须等待至少SELECT SLEEP(0.1)测试环境或SELECT MASTER_POS_WAIT()生产环境Sharding-JDBC 提供hint机制覆盖路由策略例如/* sharding hint: readwrite_splittingmaster */ SELECT ...可强制走主库。# application.yml - 仅读写分离阶段分库分表暂注释 spring: shardingsphere: props: sql-show: true # 开启 SQL 日志调试必备 dataSources: ds-master: driver-class-name: org.mariadb.jdbc.Driver jdbc-url: jdbc:mariadb://192.168.1.10:3306/mydb?useSSLfalseserverTimezoneAsia/Shanghai username: root password: pwd123 ds-slave-0: driver-class-name: org.mariadb.jdbc.Driver jdbc-url: jdbc:mariadb://192.168.1.11:3306/mydb?useSSLfalseserverTimezoneAsia/Shanghai username: root password: pwd123 ds-slave-1: driver-class-name: org.mariadb.jdbc.Driver jdbc-url: jdbc:mariadb://192.168.1.12:3306/mydb?useSSLfalseserverTimezoneAsia/Shanghai username: root password: pwd123 rules: - !READWRITE_SPLITTING type: READWRITE_SPLITTING loadBalancerName: round_robin dataSources: pr_ds: writeDataSourceName: ds-master readDataSourceNames: - ds-slave-0 - ds-slave-12.2.2 HikariCP 连接池必须隔离主从连接避免连接复用污染Sharding-JDBC 默认为每个逻辑数据源创建独立连接池但若未显式配置hikari参数可能因连接复用导致从库连接被主库事务污染。必须为每个物理数据源单独声明连接池参数# 续接上段配置在 dataSources 下为每个 ds-* 添加 hikari 配置 dataSources: ds-master: # ... 前文 jdbc-url 等 hikari: maximum-pool-size: 20 minimum-idle: 5 connection-timeout: 30000 validation-timeout: 3000 idle-timeout: 600000 max-lifetime: 1800000 ds-slave-0: # ... 同上 hikari: maximum-pool-size: 15 # 从库连接数通常略低于主库 minimum-idle: 3 # 其他参数同上注意maximum-pool-size总和不能超过 MariaDB 的max_connections。例如 MariaDB 设置max_connections500则ds-master(20) ds-slave-0(15) ds-slave-1(15) 50留出 450 连接给其他应用或监控。3. 分库分表实战按 user_id 拆分到 4 库 8 表必须处理自增主键、跨库 JOIN 和分页聚合3.1 分片键选择与算法设计user_id 的哈希取模 vs 日期范围为何哈希更适配读写分离分库分表的核心是分片键sharding key的选择。user_id作为高频查询条件天然适合作为分片键。但需警惕两种常见误用误用 UUID 作分片键UUID 字符串哈希后分布不均导致数据倾斜误用时间戳作分片键create_time导致热点写入所有新用户集中写入最新分片。Sharding-JDBC 提供HASH_MOD算法对user_id数值型取模分片保障数据均匀。具体策略分库user_id % 4→ 4 个库ds_0 ~ ds_3分表user_id % 8→ 每库 8 张表t_user_0 ~ t_user_7。此设计与读写分离天然兼容每个逻辑库pr_ds下的物理库如ds_0可独立配置主从Sharding-JDBC 在路由时先确定库再确定表全程不感知主从结构。3.1.1 分片规则 YAML 配置详解从逻辑表名到物理节点的映射链# application.yml - 启用分库分表接续前文配置 rules: # 保留前文的 READWRITE_SPLITTING 规则 - !READWRITE_SPLITTING # ... 同前 - !SHARDING tables: t_user: # 逻辑表名 actualDataNodes: ds_${0..3}.t_user_${0..7} # 物理节点表达式4库×8表32张表 databaseStrategy: standard: shardingColumn: user_id shardingAlgorithmName: db-inline tableStrategy: standard: shardingColumn: user_id shardingAlgorithmName: tbl-inline shardingAlgorithms: db-inline: type: HASH_MOD props: sharding-count: 4 # 分库数 tbl-inline: type: HASH_MOD props: sharding-count: 8 # 分表数 keyGenerators: snowflake: type: SNOWFLAKE props: worker-id: 1233.1.2 自增主键必须替换为分布式 ID否则分表后 insert 会失败MySQL 的AUTO_INCREMENT在分表后失效因为各分表的自增值独立递增无法保证全局唯一。Sharding-JDBC 内置SNOWFLAKE算法生成 64 位长整型 ID需在实体类中声明Table(name t_user) public class User { Id GeneratedValue(strategy GenerationType.IDENTITY) private Long id; // 此处必须改为 ShardingKeyGenerator(type snowflake)但 Sharding-JDBC 5.x 推荐用 Table 注解配合 keyGeneratorName // 正确写法在 Table 中指定 keyGenerator Table(name t_user, keyGeneratorName snowflake) public class User { ... } }提示若使用 MyBatis-Plus需配置TableId(type IdType.ASSIGN_ID)其底层调用 Sharding-JDBC 的keyGenerators。3.2 跨库 JOIN 与分页查询的硬伤为什么SELECT * FROM t_user u JOIN t_order o ON u.ido.user_id必须拆解Sharding-JDBC 的SELECT路由基于分片键当JOIN条件不含分片键如u.ido.user_id但o表未按user_id分片则触发广播路由broadcast querySQL 发送到所有分片结果在内存归并。这在 32 张表场景下性能灾难。解决方案只有两个方案一推荐业务层拆解为两次查询。先SELECT id FROM t_user WHERE ...获取 user_id 列表再SELECT * FROM t_order WHERE user_id IN (id_list)方案二将t_order表也按user_id分片使JOIN条件命中分片键路由变为单库单表。3.2.1 分页查询LIMIT 20,10的陷阱必须用ORDER BYLIMIT组合Sharding-JDBC 对LIMIT的处理是“各分片取 LIMIT N再内存归并后取 LIMIT N”。例如SELECT * FROM t_user ORDER BY id LIMIT 20,10会向 32 张表各发LIMIT 30取回 32×30960 条记录再内存排序取第 20~30 条。这导致内存溢出风险分片数越多内存消耗指数级增长结果错乱若未ORDER BY各分片返回顺序不确定归并后分页失效。正确写法必须带ORDER BY且字段为分片键或主键-- ✅ 正确按分片键 user_id 排序路由精准 SELECT * FROM t_user WHERE user_id 1000 ORDER BY user_id LIMIT 10; -- ❌ 错误无 ORDER BY结果不可预测 SELECT * FROM t_user LIMIT 10;4. 生产级验证用三组 SQL 测试读写分离、分库分表、事务一致性4.1 验证读写分离是否生效抓包 数据库 processlist 双校验仅看日志sql-show: true输出不够必须验证实际连接来源。执行以下 SQL 并检查 MariaDB 的processlist-- 在应用中执行 SELECT /* USE_SLAVE */ COUNT(*) FROM t_user; -- 强制走从库 SELECT COUNT(*) FROM t_user; -- 默认路由应走从库 INSERT INTO t_user (name, email) VALUES (test, tx.com); -- 写操作必走主库 SELECT LAST_INSERT_ID(); -- 验证主库写入登录主库执行SHOW PROCESSLIST; -- 查看是否有来自应用 IP 的连接且 Command 为 Sleep 或 Query -- 记录其 Id如 123登录从库执行相同命令若看到Id123的连接则证明读请求确实打到了从库。4.1.1 关键指标监控通过 ShardingSphere 的 Metrics 暴露 Prometheus 数据Sharding-JDBC 内置 Micrometer 支持需添加依赖并暴露端点!-- pom.xml -- dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-actuator/artifactId /dependency dependency groupIdio.micrometer/groupId artifactIdmicrometer-registry-prometheus/artifactId /dependency# application.yml management: endpoints: web: exposure: include: health,metrics,prometheus endpoint: prometheus: show-details: always访问http://localhost:8080/actuator/prometheus搜索shardingsphere_datasource_前缀指标重点关注shardingsphere_datasource_active_connections_total{datasourceds-master}主库活跃连接数应显著高于从库shardingsphere_sql_route_count_total{typeREAD}读 SQL 路由次数shardingsphere_sql_execute_count_total{typeWRITE}写 SQL 执行次数。4.2 验证分库分表路由准确性用sharding-sphere-sql-parser工具解析 SQLSharding-JDBC 提供离线 SQL 解析工具可验证分片逻辑是否符合预期。下载shardingsphere-sql-parserJAR 包执行java -jar shardingsphere-sql-parser-cli-5.3.2.jar \ --sql INSERT INTO t_user (id, name) VALUES (123456789, test) \ --config-path ./sharding-config.yaml输出应包含Actual SQL: ds_1.t_user_1 INSERT INTO t_user_1 (id, name) VALUES (123456789, test)其中ds_1表示第 2 个库123456789 % 4 1t_user_1表示第 2 张表123456789 % 8 1验证分片算法正确。4.2.1 事务边界测试Transactional在跨分片场景下的行为编写测试方法插入两条不同分片的记录Transactional public void testCrossShardingTx() { // user_id100 → ds_0.t_user_4 userMapper.insert(new User(100L, A)); // user_id101 → ds_1.t_user_1 userMapper.insert(new User(101L, B)); // 若任一失败全部回滚 int i 1 / 0; // 故意抛异常 }执行后检查两个分片表应均无数据。若仅一个分片回滚则说明事务未生效——此时需确认是否使用ShardingSphereDataSource而非原生HikariDataSource是否开启spring.shardingsphere.props.check-tables-on-startuptrue启动时校验分片表存在。5. 避坑清单MariaDB 读写分离的 5 个致命参数与 Sharding-JDBC 的 3 个隐藏开关5.1 MariaDB 必调的 5 个参数直接影响 Sharding-JDBC 路由稳定性参数推荐值作用不设后果rpl_semi_sync_master_enabledON开启半同步复制主库提交后不等从库 ACK 就返回导致读从库查不到新数据rpl_semi_sync_slave_enabledON从库启用半同步主库无法感知从库状态降级为异步复制slave_parallel_workers4并行复制线程数单线程复制延迟高读从库数据陈旧innodb_flush_log_at_trx_commit1每次事务刷盘主库崩溃丢失已提交事务主从数据不一致sync_binlog1每次事务同步 binlogbinlog 未落盘从库无法拉取最新日志提示以上参数需在my.cnf中[mysqld]段落配置并重启 MariaDB 生效。5.2 Sharding-JDBC 的 3 个隐藏开关文档极少提及但生产必备5.2.1props.sql-show必须设为false上线但调试期开启sql-show: true会将每条 SQL 打印到日志看似方便但在高并发下日志 I/O 成瓶颈吞吐下降 30%敏感字段如密码、手机号明文泄露。上线前务必设为false调试时临时开启。5.2.2props.check-tables-on-startup设为true防止启动即失败该参数在应用启动时检查所有actualDataNodes对应的物理表是否存在。若t_user_0表缺失直接抛SQLException阻断启动避免运行时TableNotFoundException。开发环境可关生产环境必须开。5.2.3props.max-connections-size-per-query控制单查询最大连接数当SELECT路由到多个分片时Sharding-JDBC 会为每个分片分配连接。默认值1但若分片数多如 32SELECT可能占用 32 个连接。设为3表示单查询最多用 3 个连接其余排队防止连接池耗尽spring: shardingsphere: props: max-connections-size-per-query: 35.3 最后一道防线用sharding-sphere-jdbc-core-spring-boot-starter替代旧版依赖Maven 中必须使用shardingsphere-jdbc-core-spring-boot-starterShardingSphere 5.x 官方维护而非已归档的sharding-jdbc-spring-boot-starter。前者支持MariaDB 10.5 的JSON类型解析XA事务与Seata的无缝集成PreparedStatement的批量操作优化。!-- 正确依赖 -- dependency groupIdorg.apache.shardingsphere/groupId artifactIdshardingsphere-jdbc-core-spring-boot-starter/artifactId version5.3.2/version /dependency验证依赖树mvn dependency:tree | grep shardingsphere输出应含shardingsphere-jdbc-core-spring-boot-starter而非sharding-jdbc-spring-boot-starter。本文还有配套的精品资源点击获取
延伸阅读

更多相关文章

2026/9/10 5:11:29

近红外光谱PLS定量分析建模:从数据预处理到模型部署全指南

简介:面向近红外光谱分析与化学计量学入门者,这份资源聚焦偏最小二乘法(PLS)建模的完整流程,也适用于食品、制药、农业等领域的光谱数据分析人员。近红外光谱中每个波长响应可视为自变量,目标物理或化学性质…

2026/9/10 5:06:28

CodePecker接入Gitee实战:从安全左移到DevSecOps落地

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

2026/9/10 7:06:40

AI生成代码时代,能力断层如何弥补?Code to Learn训练闭环实践

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

2026/9/10 7:06:40

RK3576开发板RTC完整配置指南:从内核到Android时区避坑

前阵子调一块RK3576开发板,功能问题都处理完了,结果客户那边反馈说设备重启后时间总是回到出厂值,日志时间戳全乱了。查了一圈,发现是RTC这块没配置干净。RK3576这颗芯片在AIoT和边缘计算项目里用得越来越多,配Linux或…

2026/9/10 7:06:40

AI文本太假怎么办?humanizer人性化改写实操指南

早上打开后台,看到一位读者的留言:“能不能出一篇关于 humanizer 的内容?我写文章基本都是 AI 帮我起草,但总觉得发出去的效果不对,说不出来哪里假。”这条留言让我挺有感触。做内容这行几年,我自己也被“A…

2026/9/10 7:01:40

T507平台适配长江存储EC150的工程级兼容性实践

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

2026/9/9 13:11:35

超人会飞不算本事:系统稳定依赖清晰规则与边界设计

开头先不绕弯子。“#斯坦李吐槽dc 所以超人是无缘无故会飞的嘛哈哈哈哈哈哈哈锤哥真是技术人才啊!#雷神 #复联”这类调侃式短标题,第一波冲击力在于它把两个宇宙的角色塞进同一个吐槽箱里,但细想一下就能发现,它真正碰到的根本不是…

2026/9/8 7:15:15

超人VS蜘蛛侠:拆解超级IP的影响力与传播方法论

把“蜘蛛侠 vs 超人”放在 CSDN 上聊,可能很多人第一反应是走错片场了。但如果把这两个角色看成“两个持续运营了 80 多年的文化产品”,你会发现,这场比较本质上是两个不同 IP 策略的长期结果对比:超人赢在定义了整个超级英雄题材…

2026/9/9 16:31:09

基于CNN的调制信号识别:MATLAB实现时频图分类实战

简介:本资源是一套面向通信工程与信号处理方向学习者、研究者的深度学习实践方案,聚焦调制信号自动检测与识别这一典型无线通信任务,解决传统方法依赖人工特征、低信噪比下性能下降等痛点。压缩包共12个文件(10.73MB)&…

2026/9/10 0:00:55

目录对比去重实战:用哈希算法精准清理重复文件

我电脑里现在还有一块换了三次机的“数据墓地”硬盘,里面存着2016年以前所有旧笔记本的完整备份。平时不觉得有什么,直到前阵子想把它整理归档,发现同一个安装包、同一批照片、同一份论文草稿,在几个不同的备份目录里反复出现。更…

2026/9/10 0:00:55

Leaflet离线地图完整Demo合集:内网部署与坐标纠偏实战

简介:这是一份面向Web GIS开发者的LeafLet离线地图示例合集,帮助开发者快速掌握离线地图从搭建到交互的完整流程。压缩包共723个文件,大小14.06MB,以319个js脚本、175个html页面和29个css样式文件为主体,配合png/svg图…

2026/9/10 0:00:55

MATLAB读取Rinex 3.02观测文件:多系统GNSS数据解析实战

简介:基于MATLAB开发的Rinex3.02版观测文件(o文件)读取代码包,面向卫星定位导航方向的学习者与研究人员,用于解决新版观测文件的数据解析、历元提取与时间转换问题。压缩包共4个文件,包含两个m脚本、一个19…

2026/9/7 16:23:03

USB Type-C PCB布局分区设计:电源、高速信号与PD协议全攻略

做硬件这行,Type-C接口算是典型的“看着简单,做起来全坑”的东西。光引脚就24个,高低速信号、电源、控制线全部塞在一个小小的连接器里,如果PCB布局不做规划,打样回来基本就是“插上没反应”、“高速掉线”、“静电一打…

2026/9/7 22:46:00

系统编程学习原型如何补齐稳定性边界

系统编程学习原型如何补齐稳定性边界预算有限时&#xff0c;我先优化明显多余的复制&#xff0c;而不是猜测性地换容器。用借用传递只读数据通常就能减少分配&#xff1a; fn parse(line: &str) -> Result<Item, Error> { /* ... */ }用基准确认热点确实在分配&am…

2026/9/9 10:21:54

雨花区哪家财务公司代理记账比较好?

在雨花区&#xff0c;企业处理财税事务常常面临诸多挑战&#xff0c;选择一家靠谱的财务公司至关重要。湖南巨勤财务管理咨询有限公司就是本地正规实体财税服务机构&#xff0c;深耕本地工商财税行业多年&#xff0c;熟悉当地工商局、税务局最新政策与申报流程。主营公司注册、…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
咨询二维码