MyCat2 使用记录与放弃复盘

MyCat2 使用记录与放弃复盘
踱鸽&水晶蟹MyCat2 使用记录与放弃复盘
做分库分表选型,最先评估的就是 MyCat2。吸引我的地方很直接:代理模式,应用像连普通 MySQL 一样连 MyCat,业务代码不需要改动。团队当时对 ShardingJDBC 的配置复杂度有顾虑,所以 MyCat2 排在第一位评估。
结论先说:搭建验证通过了,但跑现有业务 SQL 发现了几个无法绕过的限制,最终放弃,改用 ShardingJDBC。
一、为什么先评估 MyCat2
分库分表主流方案的核心差异只有一个维度:代理模式 vs JDBC 层拦截。
- MyCat2(代理模式):应用连 MyCat,MyCat 连后端数据库,应用看到的是「一个普通 MySQL」,业务代码零改动
- ShardingJDBC(JDBC 层):以 JAR 包集成进应用,在 JDBC 层拦截 SQL 做路由改写,需要引入依赖和配置
选 MyCat2 的理由:不改业务代码,迁移成本低;支持多语言项目(PHP 老服务也能用)。
选 ShardingJDBC 的理由:进程内处理,无额外网络跳转,性能更好;SQL 兼容性更强;Java 生态支持最完善。
二、搭建过程
环境
- MyCat2 版本:1.22-release
- 后端数据库:MySQL 8.0,2 个实例(3306/3307)
- 操作系统:CentOS 7,Docker 部署
核心步骤
1. 下载并配置原型库(prototype)
MyCat2 用一个 MySQL 实例作为元数据库(prototype),存储逻辑表配置:
|
2. 配置后端物理库
|
3. 启动并验证
|
分片配置示例
在 MyCat 控制台用 DDL 注解声明分片规则:
|
执行后 MyCat 会自动在后端数据库创建 t_order_0 ~ t_order_3 物理表。
基础的增删改查确实没问题,连接 MyCat 的方式和连普通 MySQL 完全一样,应用代码不需要任何修改。
三、遇到的 SQL 限制
基础功能跑通之后,开始把现有业务 SQL 在 MyCat 上跑测试,陆续遇到几个问题。
问题一:跨分片 JOIN
业务里有一个查询:订单表 JOIN 用户表,需要同时展示订单信息和用户名称。t_order 按 user_id 分片,t_user 没有分片,两个表的分片键不同。
|
报错:ERR-CODE: [MYCAT-60002], Unsupported cross-shard join
尝试用 MyCat 的 ER 关系表配置来绑定两个表,但 t_user 是未分片的全局表,配置后仍然无法正常路由。
问题二:子查询中的分片键推断失败
|
MyCat 对这类 SQL 会做全分片广播,性能退化成扫全表。数据量大时直接超时。
问题三:ORDER BY + LIMIT 分页的内存问题
|
MyCat 的处理方式是:从每个分片取 LIMIT 1020 条数据到内存合并排序,再截取第 1000-1020 条。分片数越多,合并的数据量越大。分页偏移量越大,内存压力越大。
这个查询是商家后台的订单列表接口,OFFSET 会很大,无法使用。
四、最终放弃的原因
遇到这三个问题之后,评估了改造方案:
- 跨分片 JOIN:改成应用层关联——先查订单,再批量查用户信息,在代码里组装。改造量不大,但需要修改所有涉及的 Service 层方法。
- 子查询:把 IN 子查询改成 JOIN 或者拆成两次查询。能改,但散落在项目各处,改动量大。
- 分页排序:必须改成基于游标的分页(记录上次的
create_time和id作为游标),彻底改变分页方式,前端也要配合修改。
评估之后得出结论:为了适配 MyCat2 的 SQL 限制,需要修改的代码量远超引入 ShardingJDBC 的接入成本。ShardingJDBC 以 JAR 包集成,SQL 兼容性更好,那些 SQL 基本不需要修改就能跑通。
放弃 MyCat2 不是它不好,而是它和我们项目的 SQL 模式不匹配。如果是新项目从一开始就按 MyCat 的约束设计 SQL,或者是多语言混合的项目,MyCat2 的优势才能发挥出来。
五、MyCat2 vs ShardingJDBC 选型对比
| 维度 | MyCat2 | ShardingJDBC |
|---|---|---|
| 接入方式 | 代理模式,应用改动小 | JDBC 层,需引入 JAR + 配置 |
| 性能 | 多一层网络代理,有额外损耗 | 进程内处理,性能更好 |
| SQL 兼容性 | 受限较多,复杂 SQL 支持弱 | 支持更广泛 |
| 运维复杂度 | MyCat 独立部署,需维护中间件 | 无独立中间件,应用自包含 |
| 跨分片 JOIN | 支持有限(需要 ER 关系绑定) | 支持绑定表等优化手段 |
| 社区活跃度 | 较弱,更新缓慢 | ShardingSphere 社区活跃 |
| 适合场景 | 多语言项目、SQL 简单、不想改代码 | Java 项目、现有复杂 SQL、追求性能 |
选型建议:Java 项目直接选 ShardingJDBC,MyCat2 适合的是「多语言、SQL 简单、想要对业务零侵入」的场景。
