IT 论文精读 · PAPER 19

Bigtable:一张能长到 PB 级的稀疏大表

Chang, Dean, Ghemawat 等 · Google · OSDI 2006

EN →

这篇论文干了什么?

2006 年,Google 公开了 Bigtable——它内部用来存海量数据的「一张超级大表」。Google Earth 的卫星图、每个网页的历史快照、亿万用户的个性化数据,全塞在这类表里,横跨成千上万台机器。它是继 GFS(Paper 17)、MapReduce(Paper 18)之后 Google「老三件套」的第三件,也是开源世界 HBase、Cassandra 这一整类「宽列数据库」的祖师爷。

先说说那个头疼的活儿

我们熟悉的数据库(就是银行、电商背后那种,规规矩矩的表格 + SQL 查询)在几百万、几千万行时又快又好用。可 Google 要存的东西是另一个量级:给全网每个网页存一行,就是几百亿行;每个网页每被爬一次还要留一个带日期的旧版本;不同网页有的字段有、有的没有,乱七八糟、大部分格子是空的。这么大、这么稀、还随时在长的数据,硬塞进传统数据库既装不下、也太贵。Google 需要一个专门为「大到离谱、形态松散」而生的存储系统。

它的点子:一张几乎无限大的稀疏表

想象一张 Excel,但把它的三条限制全撤了:行可以有几百亿列可以随时随地加、每个格子还能同时存好几个带时间戳的历史版本。更关键的是它「稀疏」——绝大多数格子是空的,而空格子完全不占地方,所以你尽管随意加列、留白,不心疼。这张表还有个讲究:所有行按名字(行键)排好序。于是你只要给行起个好名字(比如把网址反过来写,让同一网站的页面挨在一起),相关的数据天然就排在相邻位置,成片地查特别快。

它怎么把这张大表摊到上千台机器

表太大,一台机器装不下,就把它按行横着切成一段一段,每段(Google 叫一个 tablet)交给一台机器保管;因为行是排好序的,切出来的每段都是一个连续区间。真正的巧思在怎么读写又快又不怕机器坏:新数据进来,先在一个「流水账」上记一笔(这本流水账放在可靠的 GFS 上,机器烧了也丢不了),再顺手塞进内存里的一个「小账本」;小账本满了,就把它整理誊清、冻成一个只读的文件存到硬盘,然后换本新的接着记。查数据时,把内存里的小账本和硬盘上那一摞只读文件「合着看」——新的盖旧的。这套「先记账、攒够了誊清、旧账本只读不改」的打法,让写入飞快、机器随时坏了也能照着流水账恢复。系统还会时不时把一摞旧文件合并成一个,免得越查越慢。

它带来了什么

Bigtable 撑起了 Google Analytics、Google Earth、个性化搜索、网页索引等一大批产品;论文发表时,Google 内部已有几百个 Bigtable 集群、几万台机器在跑它。开源世界照着这篇论文做出了 HBase、又结合 Amazon Dynamo 的思路做出了 Cassandra,「宽列 NoSQL」从此成为一大类主流数据库;它那套「先写内存+流水账、再誊清成只读文件」的引擎思想,还长成了 LevelDB、RocksDB,今天无数数据库的底子。诚实的代价:它只保证单独一行内的改动是「要么全成、要么全不成」,跨很多行的复杂交易、SQL 那种花哨的多表关联,它一概不做——正是靠砍掉这些,它才换来了近乎无限的横向扩展。

一句话记住

Bigtable 是 Google 的「一张能长到 PB 级的稀疏大表」:行按名字排序、可有几百亿,列随手加,格子存带时间戳的多版本,空格不占地方。它按行把表切成段摊到上千台机器,用「先记流水账+写内存、攒满了誊成只读文件、旧文件定期合并」的引擎读写。它砍掉了通用事务和 SQL,换来近乎无限的规模——是宽列 NoSQL 的开山之作。

想看它的数据模型长什么样、三级寻址怎么在上千台机器里定位一行、还有 memtable + SSTable 的读写与合并机制? → 切到精读版