背景:4.x 到 5.x 的跨代升级
八月底我们把分库分表中间件从 ShardingSphere 4.1 升到 5.3。4.x 用的还是旧的 sharding-jdbc 单库形态,配置散在 Spring 的 xxx.yaml 里;5.x 统一成了 shardingsphere-jdbc,配置模型完全重写了。升级本以为半天搞定,实际踩了一周的坑。
配置变更:从 Spring 命名空间到 YAML 驱动
4.x 的配置长这样(Spring namespace):
<sharding:rule data-source-names="ds0,ds1">
<sharding:table-rule ... />
</sharding:rule>
5.x 改成纯 YAML,且结构换成 rules 列表,数据源先注册再引用:
dataSources:
ds0: {url: jdbc:mysql://.../db0, ...}
ds1: {url: jdbc:mysql://.../db1}
rules:
- !SHARDING
tables:
t_order:
actualDataNodes: ds${0..1}.t_order_${0..15}
databaseStrategy:
standard:
shardingColumn: user_id
shardingAlgorithmName: alg-mod
shardingAlgorithms:
alg-mod:
type: MOD
props: {sharding-count: 2}
注意 5.x 的算法用 type 声明式配置,内置算法名也变了(比如旧的 InlineShardingStrategy 换成 INLINE)。我们手写了一个 4→5 配置转换脚本,自动把旧 groovy 表达式映射成 INLINE 类型。
新特性:DistSQL 与生态统一
5.x 最香的是 DistSQL——可以用类 SQL 语句在线管理分片规则,不用改配置重启:
SHOW SHARDING TABLE RULES;
CREATE SHARDING TABLE RULE t_order (
DATANODES("ds${0..1}.t_order_${0..15}"));
另外 5.x 把 Proxy、JDBC、Scaling 整合进同一内核,后续做在线扩分片(Scaling 迁移)能复用同一套配置。
兼容性问题处理
三个真坑:
- 事务兼容:4.x 用的
Atomikos集成在 5.x 里改了包路径,启动直接ClassNotFound。5.x 推荐用内置的LocalDistributedTransaction或接 Seata,我们切到了 Seata 模式。 - Hint 注解失效:旧代码用的
HintManager.getInstance().setDatabaseShardingValue()API 包名从io.shardingsphere变成org.apache.shardingsphere,全量改了 import。 - 分页偏移下推:5.x 对
LIMIT的改写更激进,深度分页从各库取全量再归并,慢查询暴涨。给大翻页加了最大偏移限制才止住。
灰度策略
升级走的是双写旁路:新版本先以「只读代理」接一份流量做影子验证,比对返回行数和关键字段,一致率 100% 后才切主流量。这样即便有配置语义差异,也能在影子阶段抓出来。
下篇预告
这篇先把《分库分表中间件 ShardingSphere 5.x 升级实践》里的坑列了,下一篇写我们当时是怎么在线上工程里真正落地的——包括那次让领导拍桌的故障复盘。