连载中 4/20

水平拆分的三种刀法:Range、Hash 与查表

2026-07-20 · 2931 阅读 · 0 评论 · 0 赞

行往哪儿放,是个数学题

垂直拆把业务理顺之后,水平拆面对的问题是纯粹的:一张表的两亿行,怎么分摊到 N 张物理表里,让每一份都均匀、每一条都能被找到。解法历史悠久的就三种:按范围切(Range)、按哈希切(Hash)、按映射表切(查表法)。三者的差异,全在「分布均匀」和「扩容友好」这对矛盾上。

刀法一:Range——按范围切

把分片键的值域切段:订单按时间切,2026 年 1 月一张表、2 月一张表;用户按 ID 段切,1 到 1000 万一张表。路由逻辑就是简单的区间判断,一眼能看懂。Range 的王牌是扩容:数据涨了就加新段,老数据一根毫毛都不用动——按月分表,到期自然长出新表,扩容是零成本的。它的死穴是热点倾斜:新数据永远写在最后一段,最近的表承受几乎全部写入;ID 段切法也一样,新用户集中在最高段。写入热点让「分了 64 张表」变成「分了 63 张存档表加 1 张热表」,分表的意义丢了一半。Range 适合写后即冷的时序型数据——日志、账单、流水,天然的 Range 素材。

刀法二:Hash——取模均匀

把分片键做哈希再取模:slot = hash(user_id) % 64,每个键稳定落进固定分片。它的王牌是均匀——新写入被哈希摊到所有分片上,没有热点扎堆,每一张表都均衡地长大。死穴是扩容:模数从 64 改成 128,几乎所有数据的归属都变了,全量重新分布——这正是第 13 篇「翻倍扩容法」要解决的问题。工程上有个经典缓解:一开始就按大模数取模(比如 1024),每个 slot 再映射到当前的实际库表——slot 数固定,扩容只是改映射关系,这就是预分片,后面专门讲。

刀法三:查表——灵活性至上

Range 和 Hash 都是「算」出来的路由,查表法是「查」出来的:单独维护一张路由表,记录每个分片键的值落在哪个库哪个表。路由规则可以随时调整、可以精细到单个大客户定向分配,灵活性天花板最高。代价也明摆着:路由表本身要高可用、要缓存(查一次路由多一次 IO),规则一多运维就是灾难。实践中查表法多用于局部特殊路由——绝大多数流量走 Hash 算路由,个别超大商户用查表定向到独立分片,两种刀法混用。

怎么选

一张决策卡收束:数据写后即冷、按时间天然分界——Range,享受零成本扩容;数据均匀增长、读写都要摊平——Hash 加预分片,接受未来一次有方案的迁移;路由规则需要精细控制——查表法兜底特殊场景。多数交易类系统选 Hash 加预分片,日志账单类选 Range,两者组合也常见:订单主表 Hash,账单流水 Range。刀法定了,还差最关键的一个决策——拿什么键去切。分片键的选择,下一篇讲。

503

10 年全栈工程师 · 503咖啡馆主理人

#水平拆分#Range分片#Hash分片#查表法#预分片

评论 (0)

相关推荐

连载中 12/20

排查四件套:jstack、jmap、jstat、jcmd 的实战分工

jstack 看线程在干什么,jmap 看堆里装了什么,jstat 看运行时在变什么,jcmd 是统一入口。四把刀各管一段,配合着用没有查不动的现场。

#jstack#jmap#jstat#jcmd#排查工具
2026-09-16 · 5 阅读 · 0 评论 · 0 赞
连载中 11/20

GC 日志:把回收过程翻译成人话

一行 GC 日志里塞着七种信息:谁触发的、收了哪、停了多久、活了哪些。加上 -Xlog 配置,再加上日志分析工具,GC 不再是只能盯监控曲线的黑盒。

#GC日志#Xlog#日志分析#GC监控#Full GC排查
2026-09-16 · 13 阅读 · 0 评论 · 0 赞
连载中 10/20

ZGC:亚毫秒停顿是怎么炼成的

百 G 大堆停顿不到一毫秒,靠的是把搬家全部挪到并发阶段——着色指针让引用自带状态,读屏障让搬运中的对象依然可访问。代价是吞吐与内存,收益是停顿与堆大小解耦。

#ZGC#着色指针#读屏障#亚毫秒停顿#分代ZGC
2026-09-15 · 8 阅读 · 0 评论 · 0 赞