用最简单的语言介绍 CAP 理论


原文来自A plain english introduction to CAP Theorem


你可能经常听说 CAP 理论,它在分布式系统的设计中指明了一些上限。和其他的一些教程不同,我尝试用现实世界的一些情形来解释 CAP 理论。

第一章:“记忆有限公司”──你的新冒险

昨晚因为你记得老婆的生日并送给她一个生日礼物,你老婆大大地赞赏了你,也因此一个奇怪的念头出现在了你的脑海里:很多人都记不住东西,但是我非常擅长记忆,为什么我不利用这个优势来创业呢?你想得越多,就越喜欢这个主意。事实上你都已经想好了一个报纸广告来推广你的想法:

记忆有限公司──不用记住也不会忘记!

你还在因为记不住东西而苦恼吗?不要担心,现在你只需一个电话!

当你要记住东西时,拨打 555–55-REMEM 把要记住的信息告诉我们。比如,如果你忘了老板的电话,只要你曾经打电话让我们记住,现在只要拨打 555–55-REMEM,我们会告诉你!

收费:每次仅一毛!

所以,一个典型的电话对话就像这样:

  • 客户:你好,帮我把邻居的生日记住。
  • 你:好的,他的生日是?
  • 客户:1月2号。
  • 你(把生日记在你的笔记本里):记住了。在您需要您邻居生日的时候给我们打电话!
  • 客户:谢谢。
  • 你:不客气!本次收费 0.1 元。

第二章:扩大业务

你得到了 YCombinator 的投资。你的创意如此简单,只需要一个笔记本一部电话,所以你的生意像野火一样在扩张。现在你每天要接几百个电话。

现在你遇到了问题:越来越多的客户要等很久才能接通你的电话。很多人在厌倦了等待后甚至挂断了电话。更有甚者,如果你因为生病一天没上班的话,你就会错过一整天的生意──更不用提那些因此得不到信息而不满的老客户。

你觉得是时候扩大生意了,你的老婆必须帮你一把。

你开始了一个简单的计划:

  1. 你和你老婆每人一部电话。
  2. 客户们仍然只需拨打 (555)–55-REMEM 一个电话。
  3. 电话交换机会把电话平均地分给你和你老婆。

第三章:你有了第一个“糟糕的服务”

在新系统上线两天后,你接到了一个老客户 Jhon 的电话:

  • Jhon:你好。
  • 你:感谢致电!有什么可以帮您的?
  • Jhon:麻烦告诉我到新德里的航班时间。
  • 你:好的,请稍等。 (你翻找笔记本,上面没有记录 Jhon 的航班时间!)
  • 你:先生,有点问题。您没有告诉过我您的航班时间。
  • Jhon:什么?我昨天刚告诉你们!(挂断了电话)

怎么会这样?是 Jhon 在说谎吗?你想了一会,一个想法突然冒了出来:Jhon 是不是昨天给你老婆打了电话?你跑去找你老婆──确实是这样。你把这事告诉了你老婆,她也发现了这个问题。

你的分布式设计出现了一个巨大的漏洞!你的分布式系统是不一致的!总有一种可能,客户在一个人那里更新了一些信息,但是在查询的时候电话被另一个人接到。

第四章:你修正了一致性错误

你的竞争者也许会无视这个糟糕的服务,但是你不能。在你老婆睡觉时你想了一整晚,终于在早上想到一个完美计划。你叫醒了老婆:亲爱的,我们以后这样做:

  • 无论我们谁收到一条更新信息(客户让我们记住一些东西),在通话结束前我们都必须告诉对方。
  • 这样我们都能记下所有更新。
  • 当有一个查询电话的时候(客户查询让我们记住的信息),我们就无需互相询问──因为我们都已经记住了最新的信息。

“现在只剩下一个问题”,你说,“我们俩都必须参与到一个「更新」请求中,所以我们不能在那段时间内并行工作了。比如,你收到一个更新请求然后告诉我去记住更新,这时我就不能接其他电话了。但这是可以接受的,因为大部分请求都是「查询」(客户更新一次但是会查询多次)。另外,无论如何我们都不能给出错误信息。”

“不错”,你老婆说,“但是你刚才想出来的这个新系统还是有一个缺陷:如果我们俩有一个人有一天不能来上班怎么办?那天,我们不能接受任何「更新」电话,因为另一个人不能做更新操作!这样我们就有了可用性问题,比如,我接到了一个更新电话,但是我结束不了那通电话,因为即使我已经在笔记本上记住了更新操作,但是你做不了更新操作!”

第五章:你想到了一个最伟大的解决方案

你开始意识到分布式系统并不像一开始你想的那么简单。一个一致并且可用的解决方案有这么难吗?对别人来说也许是,但是你不一样!第二天一早你想出了一个你的竞争对手做梦也想不到的方案!于是你又把你老婆叫醒了。

“你看”,你说,“这样做我们就能即一致可用”。这个方案和你昨天的方案很类似:

  • 当我们接到一个更新请求时(客户让我们记住一些东西),在结束通话之前,如果对方在办公室,我们直接告诉对方,这样我们都能记录所有更新。
  • 但是如果对方不在(没来工作),我们给对方发一封关于本次更新的邮件。
  • 第二天当对方上班的时候,在接客户电话之前他的第一件事是查看邮件并记录更新。

“天才!”,你老婆说,“这个系统我找不到任何缺陷,马上开始执行!记忆有限公司现在是一致并且可用。”

第六章:老婆发火了

在一段时间里一切正常。你的系统是一致的,甚至你们俩有一个没来工作时也一切正常。但是如果你们来了而有个人没有提醒对方更新呢?想想你最近做的──经常早早把老婆叫醒说你的那些伟大想法的废话。如果更新的电话是你老婆接到,但是她因为生你的气没有叫你一起更新怎么办。你的创意就完蛋了!现在你的想法是一致可用的,但是不能保证分区容错

你为了保证分区容错可以在和你老婆和好之前不接任何电话──但是你的系统又是不可用的了。

第七章:结论

现在再让我们看看 CAP 理论。它阐述的是在你设计一个分布式系统时,你不能同时满足一致性可用性分区容错性

  • 一致性:一旦你的客户更新的信息,他们打电话来查询时总能得到最新的信息──无论他们多快打来查询电话。
  • 可用性:只要你和你老婆有一个人来上班,记忆有限公司总能提供信息。
  • 分区容错性:如果你和你老婆的联系断了记忆有限公司还是能正常工作。

彩蛋:雇佣一个跑腿的职员来保证最终一致性

你的想法还有一个补充。你可以雇佣一个跑腿的职员,当一个人的笔记本更新时,他会更新另一个人的笔记本。这个方法最大的好处在于,跑腿职员可以在后台工作,如果你或你老婆接到一个更新请求时,你们俩不会阻塞在等待对方更新上。这是很多 NoSQL 系统工作的方式:一个节点在它本地更新,一个后台进程同步其他节点。唯一的问题是会在一段时间内失去系统一致性。比如,你老婆接到了一个更新请求,在跑腿职员更新你的笔记本之前,你接到了同一客户的查询请求,所以客户就得不到一致的响应。但是如果能限制这种场景的话,这并不是一个坏主意──比如,假设客户不会非常快地忘记事情,他们只会在5分钟之后来电。

这就是用最简单的语言解释 CAP 理论和最终一致性:)。


 Toc
 Tags