翻译自:A plain english introduction to CAP Theorem

大白话介绍CAP理论

在设计分布式系统的时候,你可能经常听说有关CAP理论,它指定了某些上限。跟我其它大部分介绍教程一样,让我们通过对现实世界的情况进行类比,来了解CAP。

第一章:“记忆公司” - 你的新事业

昨天晚上,由于你记得妻子的生日,并给她送了一个礼物,她对你表示了感谢。此时,一个新奇的想法出现在了你的脑海中:人们的记忆力通常特别差,而你却特别擅长记忆,那么为什么不通过这个能力来开创一项事业呢?你越想越兴奋。你甚至想要在报纸上来解释你的这个想法。

记忆公司 - 永远不会忘记,甚至不要去回忆。
你是否还在烦恼经常忘记许多东西?不要担心,一个电话就能让你搞定!
当你需要记起某些东西,只需要拨打555-55-REMEM,告诉我们你想要记忆的东西。比如,告诉我们你老板的电话号码,而你并需要去记忆。当你需要时,只需要拨打[(555)-55-REMEM],我们就会告诉你,你老板的电话号码。
费用:每次只需要$0.1

典型的对话可能如下:

  • 顾客:我可以把我邻居的生日存起来吗?
  • 你:当然,什么时候?
  • 顾客:1月2号
  • 你:(在你的笔记本上记下顾客的需求)。当你想知道你邻居的生日时,随时都可以打给我们。
  • 顾客:谢谢!
  • 你:没有问题!此次收费$0.1

第二章:扩大规模

YCombinator对你进行了投资。你的想法如此的简单,只需要一个电话跟笔记本,却能如此的有效。越来越多的人知道了,你开始每天接到几百个电话号码。

但是也出现了一些问题,越来越多的顾客等待跟你通话。很多人等的不耐烦了,直接挂了电话。而且当某天你生病了,你就无法工作,那么你就丢掉了这一天的生意,更不用说在这天需要获取信息的顾客。因此你决定扩大规模,让你的妻子来帮你。

你进行了一次简单的尝试:

  1. 你跟你的妻子都有一个分机号
  2. 顾客仍然拨打(555)-55-REMEM这个号码
  3. PBX会把顾客的号码转给空闲的人

第三章:你的第一个差评

在实现了这个新系统两天之后,你的忠实顾客Jhon打来了一个电话。事情的经过如下:

  • Jhon:你好

  • 你:我有什么可以帮到你的?

  • Jhon:你可以告诉我,我去新德里的航班是什么时候的吗?

  • 你:当然,请稍等

    (你查了下你的笔记本)

    (但是并没有找到关于Jhon的航班信息)!!!

  • 你:先生,应该是哪里搞错了,你并没有告诉我你去新德里的航班信息

  • Jhon:什么!我昨天刚打电话跟你说过!(挂了电话)

发生了什么?Jhon撒谎了吗?你想了一下就知道原因了。难道是Jhon昨天的电话被你妻子接到了?你走到你妻子的办公桌前,查了一下她的笔记本。果然如此。你把这件事告诉了你的妻子,她也意识到了这个问题。

你的分布式系统中出现了一个严重的问题!你的分布式系统并不具有唯一性!顾客可能通过你或者你的妻子更新了他的信息,但是下一个电话却去到了另一个人那里,那么顾客就会得到不一致的回答。

第四章:修复一致性问题

在你妻子睡觉时,你在床上想了整晚,在早上时想到了一个完美的解决方案。你叫醒你的妻子,并把方案告诉了她:

  • 当任何一个顾客要更新信息时,在电话结束前,我们要把更新的信息告诉对方
  • 这种我们可以记下任何的更新信息
  • 对于任何要进行信息查找的电话(当顾客已经将信息存储在我们这里),我们不需要与对方进行交谈。因为我们已经将最新的信息记录在我们的笔记本上,我们可以直接找到它

但是还有一个问题,那就是当一个“更新”请求过来时,会涉及到我们两个人,在这段时间内,我们无法进行工作。比如,当你获取一个更新请求,并且将其告诉我时,我们就不能接别人的电话。但是这并没有什么问题,因为大部分打给我们的电话都是为了进行查找(一个顾客更新一次,但是会查找多次)。无论如何,我们都不能提供错误的信息。

你的妻子说:“很好,但是这个系统还有一个你没有想到的缺点,那就是如果某天我们其中一个不能进行工作,怎么办?在那一天,我们就不能接受任何更新请求,因为另一个人没法进行更新!我们将会有可用性问题,例如,如果一个更新请求到了我这里,我将无法完成,虽然我可以将信息更新在我的笔记本上,但是我没办法将其更新在你的笔记本上,因此,我没法完成这个请求“

第五章:你想出了一个更好的解决方案

你开始意识到,为什么一个分布式系统并没有你开始想的那么简单。难道对于“一致性与可用性”问题没有一个可行的解决方案吗?对于其他人来说可能很难,但是对你来说并不是这样。在第二天早上,你想到了一个你竞争对手做梦也想不到的解决方案!你再次早早的将你的妻子叫醒。

你告诉她:“你看,按照这样子做,我们就可以保证一致性与可用性。这个方案与我昨天告诉你的差不多”:

  • 任何时候,当一个顾客想要进行更新时,在完成请求之前,如果另一个人可用,那么我们将更新信息告诉他。这样我们就都可以进行更新
  • 但是如果另一个人不可用(不想上班),我们就将更新信息通过邮件告知
  • 当另一个人第二天上班时,在他接第一个电话之前,他首先要查看邮件,将所有更新信息写在他的笔记本上

你妻子对你说,你他娘的真是一个天才!这个系统我再也找不出任何缺点了,让我们开干吧!记忆公司,现在具有一致性与可用性

第六章:你妻子生气了

一段时间内,一切都很顺利。你的系统具有一致性。即使你们其中一个不想工作时,你的系统也运行的很好。但是如果你们两个都在工作,但是其中一个没有给对方信息进行更新时怎么办?不要忘了这几天,你为了你的天才想法早早的叫醒了你的妻子。如果你的妻子对你很生气,虽然接了电话,但是却不把更新的信息告诉你?那么你的想法就完全破碎了。你的想法一直以来都具有一致性与可用性,但是却不具有分区容忍性

你为了具有分区容忍性,在安慰好你的妻子之前,你决定不接任何的电话。那么在这段时间内,你的系统就不具有可用性。

第七章:总结:

现在让我们来看看CAP理论,它指出,当你在设计一个分布式系统时,你们不可能同时获得一致性,可用性以及分区容忍性,你只可以获得其中的两种:

  • 一致性:一旦你的顾客有更新请求时,不管接下来他们何时进行请求,以及请求如何频繁,总是可以获取到最新的信息
  • 可用性:你们任何一个在上班,记忆公司将会永远可用
  • 分区容忍性:即使消息在你跟你你妻子之间丢失了,记忆公司也依然能够进行工作

Tips:通过跑动的职员保证最终一致性

这里还有一个值得思考的问题。你可以雇佣一个跑动的职员,当你或者你妻子的笔记本更新时,让他去更新另一个的笔记本。这里最大的好处在于,你或你妻子的更新操作不会因为等待另一个人的更新完成而进行阻塞,可以让职员在后台进行工作。这也是许多NoSql系统的工作方式,一个节点在本地进行更新,一个后台进程对其它节点进行同步。唯一的问题在于,某些时候将会丢失一致性。比如,顾客的电话先打给你的妻子,在职员还没将数据更新到你笔记本上时,顾客的电话又打了过来并转到了你这里,那么他就不会得到一致性的回复。话虽如此,但是在某些情况下,这也不失一个好的方法。比如,假设顾客在五分钟之内并不会这么快就忘记他说的信息。

这就是对CAP以及最终一致性的大白话解释。