一杯咖啡的时间,聊聊技术与成长
扩容:成倍扩容与预分片
取模分片的账迟早要还:模数从 32 改到 64,几乎所有数据的归属都变了,全量重新分布。翻倍扩容法让搬家量降到一半,预分片则更进一步——1024 个槽从第一天起固定不动,扩容只改槽到库的映射。设计期为未来的自己铺路,扩容那天才不手抖。
分片友好的主键:ID 里埋下路由基因
分库之后,全表共享的自增主键第一个阵亡——每个分片各自从 1 数起,撞车只是时间问题。全局唯一、趋势递增、还能算出路由,分片主键的三重身份缺一不可;基因法把分片键的哈希直接埋进 ID,让订单号自己会走路。
分片后的事务:本地事务的边界与柔性方案
拆库之前一个事务包住所有写,拆库之后事务的边界画在了分片线上——带分片键的写落单库,事务照旧;跨片的写被中间件拆成多个本地事务,失败就是部分提交。最好的解法是设计期就把事务锁进单库,剩下的用柔性方案兜底。
跨分片查询(下):分页、JOIN 与广播表
跨片分页是归并账本里最贵的一页:取第 100 页的 10 条,中间件要向所有分片要回前 1000 条——翻得越深,浪费越大。JOIN 则在分片下全面受限:同片能连,跨片靠冗余。绑定表与广播表,是把 JOIN 从灾难变回日常的两件工具。
跨分片查询(上):聚合与排序的归并代价
不带分片键的查询不是不能跑,是要付出「扫全部片、再归并」的代价——count 要加法归并,avg 要先拆 sum 与 count,全局排序要堆归并,group by 最重。把每一类聚合的归并账本算清楚,才能在「加一跳异构」和「接受归并开销」之间做对选择。
中间件之下:SQL 改写、归并与执行的流水线
一条逻辑 SQL 进来,中间件悄悄做了什么?表名换成真实表、limit 改写成重算的分页、avg 拆成 sum 加 count——然后并发打到多个分片,再把结果归并回来。看懂这条五步流水线,分片环境里九成的诡异问题都能自己定位。
ShardingSphere-JDBC 接入实战:分片配置跑起来
说了六篇原理,该让代码跑起来了。引入 shardingsphere-jdbc 依赖、声明逻辑表与真实表节点、写好分片算法——三十行配置,订单表按 user_id 取模的 8 库 32 表就转起来了。配置里的每一个字段,都对应着前几篇的一个决策。
路由:从代码 if-else 到中间件
分片键定了,路由规则算得出数据在哪儿——但这段逻辑放在哪儿执行,决定了系统的可维护性。硬编码灵活在手里、死在未来;代理层集中但多一跳;SDK 内嵌在进程里,性能与治理兼得。三种落法对应系统规模的三段演进。
分片键:一次选择,终身锁死
切多细、用什么刀法都能改,唯独分片键定了就改不动——所有查询都必须带上它,不带就全分片扫荡。订单系统选 buyer_id 还是 seller_id 还是订单号?基因法给出第三条路:把两个维度都埋进 ID 里。这个决策的代价,要用很多年偿还。