4.1 分片把大表摊开


4.1 分片(Sharding):把一张大表摊到多台机器

分片是分布式数据库"摊开"数据的基本动作:把一张逻辑上统一的大表,按某个键切分成多个独立的"物理片",各自住到不同节点。本节把哈希、范围、列表、目录四种分片细则逐个讲透,并重点讲清那个决定成败的细节——分片键怎么选。

一次"悄悄帮你查到"的联表,暴露了分片的存在

你有没有想过:数据明明散在好几台机器上,可你提交一句 SQL,它居然秒回?数据库能在背后"悄悄"把表切了还不让你知道——这就是分片要干的"门面功夫"。理解分片,先从这个"悄悄"入手:它能切、能查、还能让你看不出它切了。

学习目标

阅读完本节,你应当能够:

  1. 区分逻辑表与物理片的差别,解释"分片对应用透明"的含义。
  2. 对四种分片方式各举一个使用场景,说明为何用它。
  3. 用一个判断流程挑选分片键:要均匀、要场景匹配、要支持你的查询模式。

一次联表查询暴露出分片的存在

先看一个现象:你在分布式库上跑一条"查某个用户 90 天内的全部订单",数据却散在四台节点上。这个库之所以还能秒回,是因为它"悄悄"把订单表按用户 id 分片——这位用户的所有订单刚好挤在同一片节点,于是本地一查就完事,不必全表抓取。这个"悄悄"正是分片的意义所在:应用端根本不知道表被切了,它只管提交 SQL,剩下的由分片层搞定。这种"对应用透明"的切分,就是分布式数据库的门面功夫。

一、四种分片细则

哈希分片:对分片键取哈希再对片数取模,数据均匀散开、并发摊平,但范围查询要跨片、扩容要重映射。适合"没明显热点、点状读写为主"的业务。

范围分片:按分片键的数值区间切段。区间查询友好、管理直观,但分界处很容易热门——比如维度按时间切,月末月初那个桶最忙。适合"读写都集中在有序区间"的业务。

列表分片:按枚举值归类,比如按城市分。最直白,但粒度过粗、桶间易失衡(热城爆、冷城闲)。适合枚举值天然均衡的小型场景。

目录分片:单独维护一张"数据块 → 节点"的映射表,最灵活、可按需手工调配,但引入了额外元数据开销,还带来映射表的单点与一致性问题。用作兜底与特殊调配很合适。

四种分片细则一图对照

下面这张 SVG 把四种分片方式对"同一批数据"的结果并排画出来,方便你直观比较分布形态:

四种分片:同一批数据怎么被切分

四种分片:同一批数据怎么被切分

二、分片键:成败都在这一下

分片键(shard key)是被拿来做切分依据的字段——它决定了记录落到哪个片。选分片键有三个要求交织:一是分布要均匀,否则某一键的桶爆了,别的桶闲着,等于退化回单机;二是要使"最强查询模式"尽量落在单片,才能吃到数据本地性的甜头;三是尽量不要频繁改动,因为改分片键往往牵动全量迁移。

举一个分活失败的例子:某社交平台把"粉丝表"按用户 id 哈希分片,看起来很均匀,但大家平时查的其实是"某人关注里的最近动态",这种查询却是同一个人跨了很多片,于是每条请求都变成跨片大采集,性能崩了。教训就是分片键选错了路由宝:均匀是够了,可没照顾"哪类查询最频"。反过来,把订单按"下单时间范围"分片,卖场的月末大促又会把热点压到单一区间。所以好的分片键,得在"均匀"与"匹配查询"之间反复权衡。

三、分片键选择的五步排查

遇到新表不知道该拿什么当分片键,我按这个顺序问自己:第一步,最频的查询是单点还是范围? 单点用 id 哈希、范围用时间切段。第二步,id 是稳定的吗? 会变的分片键别用。第三步,写入有多少热点? 热点显著的绕开。第四步,扩容是切片还是加节点? 决定你选哈希还是范围。第五步,跨片操作是否可避免? 遇到必须跨片的 join,考虑用"同驻分片"(把关联表按同一键分到同片)来化解(第 7 章有展开)。

四、扩容时,四种分片的迁移成本大不同

选分片方式时,很多人忽略一件事:将来扩容要付多少"搬家钱"。四种方式在这个维度上天差地别:

哈希分片:取模的分母一变,几乎所有记录的新家都变,需要全量重分布——迁移成本最高。

范围分片:扩容只要在区间边缘切一刀,被切的那块轻量搬走、其余原地不动——成本最低,这也是它管理直观的一个加分项。

列表分片:要在已有桶里再拆细,往往牵动路由规则和跨桶查询,动不动就要大改——成本高、风险也高。

目录分片:最灵活——映射本身就是一张可改的表,扩容时改几条目录即可,迁哪些、迁多少全由调度决定——成本可控,但依赖目录维护。

方式 扩容成本 扩容时的迁移动作 可否热扩容
哈希 全量重新 hash 难,要靠一致性哈希缓解
范围 切一刀搬少量 易,动态加区间
列表 拆桶改路由 难,规则易崩
目录 改目录表即可 易,全由调度说了算

实际工程里,为了既保留哈希的均匀、又缓解扩容的全量重 hash,普遍做法是引入一致性哈希:把节点和键都映射到一个逻辑环上,扩一台新节点时只影响落在它前后两段的那批键,大部分记录原地不动,迁移量从"全量"降成"局部"。这背后还是那句话——接受一点额外的元数据与调度开销,换扩容时的安稳。等你真开始动手实践扩容方案,十有八九会踩到它的进阶版,这里先给你埋个概念,后面 4.4 讲元数据时会再碰一次。

看了这四行你该明白,"扩容顺滑"本来就是分片方式的一个核心取舍维度,它跟均匀性、查询友好站在同一条天秤的两头——选片不只挑当下好用,还要为将来扩得动留一条后路。这就是分片选型里最容易算漏的那一笔账,也是很多系统"上线时飞快、一年后扩容再也不敢动"的原因。

本节要点回顾

  • 分片=切表:逻辑一张大表、物理多片,对应用透明。
  • 四种细则:哈希/范围/列表/目录,匹配不同负载。
  • 分片键是命门:要均匀、匹配最频查询、稳定不多改。
  • 跨片是灾难:能避免就靠同驻分片,避免就认命付网络账。

把表分成片还远远不够——一片不合副本,机器倒了数据还在谁那?下一节 4.2 讲复制策略:怎么给每片留备份、读写模型怎么配才不写出瓶颈。


作者与出处
原作者: 灏天文库
来源:灏天文库
整理: 灏天文库整理
由灏天文库平台收录,内容或由平台用户上传,仅供学习交流
发布者: 作者: 灏天文库 转发
评论区 (0)
U