专业书籍精读 · DDIA · 第 6 章

分区:一份数据太大,切开放到多台机器

Designing Data-Intensive Applications · Ch 6 · Martin Kleppmann · 2017

EN →

这一章讲什么?

上一章说的是把同一份数据抄好几份(复制)。这一章解决的是另一个问题:数据本身太大了,大到一台机器根本装不下、也扛不住。淘宝上亿条商品、微信几十亿条消息——没有哪台机器的硬盘和 CPU 顶得住。办法很直白:把一大坨数据切成很多小块,每块交给一台机器管。这个「切开分放」的动作,就叫「分区」(也叫分片)。

先打个比方

想象一座巨大的图书馆,书多到一个书架放不下。你有两种分法:一种是按书名首字母——A 到 F 放 1 号柜、G 到 M 放 2 号柜……另一种是给每本书算个「暗号」随机打散——同一个书名永远算出同一个暗号,按暗号丢进对应的柜子。前者找「所有 D 开头的书」很方便(都在一起);后者每个柜子塞得一样满、谁也不会特别挤。数据库切数据,用的就是这两招。

旧世界为什么难

不切开,问题是死结:一台机器存不下那么多数据、也算不过来那么多请求。而一旦切开,新麻烦立刻冒出来——切得不匀会「堵车」。要是所有热门请求恰好都落在同一个柜子(比如某个明星发了条动态,几千万人同时来看),那台机器照样被压垮,其他机器却闲着。这种「一个格子被挤爆、其他格子空荡荡」的情况,是这一章反复要对付的敌人。

切开之后的三个真问题

① 怎么切才匀? 按首字母切,简单、还方便按顺序找一段;但容易堆热点(大家都查最新的)。按暗号打散,最匀;但没法「按顺序取一段」了(相邻的书被丢到了天南海北)。各有各的甜头和苦头。

② 加了新柜子,书怎么搬? 图书馆扩建、加了几个新书架,总不能把全馆的书推倒重排——那得关门好几天。聪明的做法是只从每个旧柜挪一小部分书到新柜,动得越少越好。

③ 要找一本书,怎么知道它在哪个柜? 得有个「前台」或一张「目录」告诉你:你要的这条数据,归哪台机器管。柜子搬动后,这张目录还得及时更新。

那这跟「抄好几份」是一回事吗?

不是,但它俩是黄金搭档。复制是「同一块内容,抄给几台机器各存一份」(防坏、就近、分摊读);分区是「把整个大数据集切成不同的块,各机器只管其中一块」(为了装得下、算得动)。真实系统几乎两个一起上:先切成很多块,每块再各抄三份放到不同机器上——既装得下,又坏得起。

一句话记住

分区 = 把一个大到单机装不下的数据集切成很多小块,每块交一台机器管,为的是能扩展。切法有两种:按顺序切(方便按段找、但易堵)、按暗号打散切(最匀、但没法按段找)。真正的难点是别让某一块被挤爆(热点)、加机器时少搬数据、以及找得到每条数据在哪。它和上一章的复制通常配套使用。

想进到具体机制、二级索引与再平衡策略、示意图? → 切到精读版