路由逻辑放在哪儿
分片键和刀法定完,「这条数据在哪儿、这条 SQL 去哪儿」的答案已经能算出来了。剩下的问题是工程问题:这段计算逻辑写在哪儿?写死在业务代码里、架一个独立代理,还是打包成 SDK 塞进每个应用?三种落法对应三个规模阶段,也对应三种命运。
落法一:硬编码——最早的自由
最朴素的实现:业务代码里直接算——按分片键取模,拼出真实的库表名,拿到对应数据源执行:
int slot = (int) (userId % 32);
DataSource ds = dataSourceMap.get("db_" + (slot % 8)); // 8 库
String table = "t_order_" + slot; // 32 表
// 手动拼 SQL 执行……起步阶段这么写完全合理:零依赖、所见即所得、调试直观。但债很快压上来:每张分片表都要自己管路由,跨片查询要自己写循环聚合,数据源切换、连接池管理全部手搓;更要命的是路由规则改一处要动所有业务代码。硬编码的尽头是一坨谁都不敢动的路由散弹——它的历史使命是验证分片方案,不是承载生产规模。
落法二:代理层——集中治理
第二种落法把路由抽出来做成独立服务:应用连代理,代理伪装成一个 MySQL(对应用来说还是「一个库」),收到 SQL 后解析、改写、路由到真实分片,把结果归并回来。MyCat、ShardingSphere-Proxy 是这一路的代表。优点非常诱人:业务代码零改造,分库分表对开发完全透明,路由规则集中在代理层一处治理,DBA 也能直接用客户端连上来查。代价同样明显:所有流量多一跳网络,代理自身是新的性能瓶颈和单点(要集群部署、要监控),SQL 解析器对复杂语句的支持永远有长尾——一条写法刁钻的 SQL 在代理上出问题,排查链路凭空多一层。重运维、强管控的团队与异构语言并存的环境,适合这一路。
落法三:SDK——进程内的透明层
第三种落法把路由做成 jar 包,嵌在应用进程里:应用的数据源换成 SDK 提供的分片数据源,SQL 进来后 SDK 在进程内完成解析、改写、路由、归并,直连真实分片库。ShardingSphere-JDBC 是代表,下一篇就讲它的接入实战。性能是它最大的牌——没有中间跳数,数据不经过第三方进程;代价是语言绑定(Java 生态深度受益,其他语言用不上)和升级成本——SDK 版本散落在几十个应用里,规则变更需要推动各应用升级。互联网公司的主流选择是这一路:性能优先,接受升级的运维成本。
演进的顺序感
三种落法不是三选一的并列题,是有时间顺序的单选题:小规模用硬编码验证方案,规模上来换 SDK 承载生产,异构语言或强管控场景补代理层。无论哪一种,底层职责都一样:解析 SQL、按分片键算路由、改写 SQL、执行、归并结果——这个五步流水线是所有分片中间件的心脏,下一篇先用 ShardingSphere-JDBC 把流水线跑起来,再拆开看它每一步干了什么。
评论 (0)