IT 论文精读 · PAPER 25

F1:能扩展的分布式 SQL 数据库

Shute 等 · Google · VLDB 2013

EN →

这篇论文干了什么?

2013 年,Google 一队工程师公开了 F1——一个撑着 AdWords 广告业务(Google 当时最赚钱的产品)跑的数据库。它厉害在同时拿到了两样过去被认为不能兼得的东西:像大互联网系统那样能无限扩容,又保留了老式关系数据库的完整 SQL、事务和强一致。它取代了 AdWords 底下那套手工拆分、维护到令人崩溃的 MySQL。

旧世界的痛

过去十几年,做大系统的人被逼着做一道二选一。一边是老牌关系数据库(会 SQL、能开事务、数据永远对得上),可一旦数据大到一台机器装不下,就得手工把表「切成很多块」摊到很多机器上——切完之后跨块的事务、跨块的查询、再切一次,全都是噩梦。另一边是新兴的 NoSQL(像 Bigtable),天生能摊到几千台机器、随便扩,可代价是丢掉了事务、丢掉了 SQL、数据还常常「暂时对不上」。Google 自己就是从 MySQL 逃到 NoSQL 的,工程师们逃过去之后天天怀念以前的好日子。

那个点子

F1 的赌注是:不用二选一。底下先垫一个天生就能扩、又天生强一致的存储层——上一篇讲过的 Spanner(Google 那个用「诚实的时钟」做全球一致事务的数据库);然后在它之上,把关系数据库那套完整 SQL、事务、索引原封不动地盖回来。换句话说:把扩容这件难事甩给下面的 Spanner 扛,F1 自己专心把「好用的数据库」这层做漂亮。

怎么做到的?

难点在一处:Spanner 为了让全球的数据永远一致,每次写入都要跨机房投票拍板,——一次提交要几十到上百毫秒,比本地数据库慢一大截。F1 用三招把这份慢摊平:

一、把一家客户的整棵数据装进「同一个文件夹」。一个广告主,底下有很多广告系列,每个系列又有很多广告组——F1 让这一整棵树在磁盘上物理挨着放、归到同一格。于是「取出这个客户的全部资料」是一次本地取件,改动也在一格里就地完成,不用满机房乱跑。

二、改数据不上锁,保存时再核对。就像多人编辑一份共享文档:你不锁住它慢慢改,而是先随便读、随便改,到「保存」那一刻才检查一下——这些内容有没有被别人动过?没动就落盘,动了就重来。这样慢吞吞的客户端不会一直占着锁堵住别人。

三、既然每次问答都是慢速的「越洋电话」,就别一句一句地问。F1 把应用改成一次批量多问、能并行的同时问,用问的次数变少、变并行,把每次的慢摊薄。结果 AdWords 网页整体反而不比老 MySQL 慢。

一句话记住

F1 证明了「能无限扩容」和「有完整 SQL+事务+强一致」不必二选一:把扩容甩给底下的 Spanner,自己专心盖回好用的关系数据库;再用「整棵数据归一格、改动不上锁只在保存时核对、批量并行地问」这三招,把跨机房同步带来的慢摊平。它撑起了 Google 最赚钱的 AdWords。

想看架构图、层级表怎么摆、乐观事务怎么跑,以及真实延迟数字? → 切到精读版