IT 论文精读 · PAPER 54

Dynamo:亚马逊的高可用键值存储

DeCandia 等 · Amazon · SOSP 2007

EN →

这篇论文干了什么?

2007 年,亚马逊(Amazon)公开了自家内部存储系统 Dynamo 的设计。它撑着的是购物车这类场景:黑五大促、机房里总有机器在坏、网络时不时抽风,可你往购物车里加一件商品,这一下永远不能失败。Dynamo 的整篇论文,就是在回答一个问题:怎么造一个「永远能写进去」的存储?

它做了个别人不敢做的取舍

传统数据库信奉一条铁律:数据必须时刻一致——所有人看到的永远是同一份最新值。为守住这条,遇到故障或网络分裂时,它宁可拒绝服务也不肯让数据出现分歧。Dynamo 反过来赌:宁可让数据暂时有点分歧,也绝不拒绝用户。对购物车来说,「加购物失败」比「购物车里短暂多出一件、待会儿再对账合并」糟糕得多。

数据放在哪台机器?——一张圆桌

成千上万台机器,一个键(比如某用户的购物车)该存哪台?Dynamo 把所有机器想象成围坐一张圆桌,每台占一个座位号。给键算个号,顺着圆桌往下找到的第一台机器就负责它,再连同后面两台一起存三份备份。妙处在于:加一台或走一台机器,只影响它两个邻座,绝大多数数据纹丝不动——扩容缩容都不用大搬家。

机器坏了呢?——先让邻居代收

要写的那台机器正好宕机了怎么办?Dynamo 不等它——先把数据交给圆桌上下一个还活着的邻居「代收」,并附一张便条写清「这本来是张三的」。等原主机恢复,邻居再把代收的东西连同便条一并送还。于是写入几乎永远能落地

那分歧了怎么收场?

如果同一个购物车在两台机器上各被改了一下,就出现了两个版本。Dynamo 不擅自替你决定谁对——它把两个版本都留着,等下次有人来读时一起交出去,让应用自己合并:购物车的合并规则很简单——取并集,两边加的东西都留下(大不了多留一件,总好过丢东西)。代价是诚实的:应用得自己写这套「遇到两个版本怎么合」的逻辑,不像传统数据库那样甩手不管。

一句话记住

Dynamo 为了「永远能写进去」,主动放弃「时刻一致」:用圆桌轮值决定数据存哪、加减机器不用大搬家,机器坏了先让邻居代收,数据出现分歧就多版本并存、读时交给应用合并。这套「最终一致(eventual consistency)」的打法,点燃了后来 Cassandra、DynamoDB 等一整代 NoSQL 数据库。

想看一致性哈希环、向量时钟和 R+W 读写法定人数的机制? → 切到精读版