返回 登录
0

用这个故事解释CAP,就是这么简单!

阅读3473

图片描述

在设计分布式系统时,常常会用到“CAP理论”来权衡和考量某些“上限”情形。下面要讲的这个故事,能帮助小伙伴们更容易理解“CAP理论”——咳咳,排排坐,吃果果,开始讲故事啦!~(≧▽≦)/~

第一集:商机无处不在——A君的“记忆公司”初诞生!

从前有个A君,他好像天生记忆力就特别好。俗话说,健忘是男人的通病,但A君不一样,大到结婚纪念日、老婆大人生日,小到“两人第一次约会纪念日”,“家里的宠物汪生日”,他都能如数家珍。这不,昨晚正是老婆大人生日,他即时送惊喜,哄得老婆大人忒开心。“我的记忆力咋就这么赞呢?”他一阵陶醉……突然,一道灵光闪过,“何不开个公司好好利用这天赋来赚钱?!”而且新公司的广告可以这么打:

图片描述

A君说做就做,他的“记忆公司”就这样开张了,员工规模嘛,一个人——他自己。

“记忆公司”的日常业务通话是这样的:

顾客:你好,我想存下我老丈人的生日。
A君:请问是什么时候?
顾客:1月2日。
A君:(在笔记本上记下后)当你需要用到它时,欢迎随时致电我们。
顾客:非常感谢。

第二集:是时候扩大规模了!

由于A君贴心的服务质量,当然还有他磁性低沉的迷人嗓音,顾客来电络绎不绝。不久后,“记忆公司”就得到某著名创业孵化器的大笔赞助了。你想啊,A君只需要 一个笔记本和一个电话就能开展业务,业务规模当然扩张得很迅速。不知不觉A君每天的电话业务量快破千,这下忙得他焦头烂额。

还有更严重的问题来了。越来越多顾客打电话过来发现永远占线,很多人等得不耐烦就挂断了。再加上A君最近实在太累,终于有天病倒了没有开工,那一整天的业务就这么泡汤了,而对于那天急需信息的顾客来说,不满的情绪更是直线飙升。

是时候扩大公司规模了!A君立刻动员亲爱的老婆大人来帮忙。

而且他设计了一个简单的新系统:

  • 我和老婆一人一部分机。
  • 顾客依然拨打(888)–88-REMEM,他们只需记住这一个号码。
  • 通过一部PBX(电话交换机)将每个顾客来电平等发送到我和老婆两人中正空闲的一部分机上。

第三集:遭遇了第一次服务危机

就在新系统上线两天后,A君接到忠实顾客老王的电话:

  • 老王: 喂,兄弟!
  • A君: 哎,老王,这次有什么要帮忙的?
  • 老王: 帮我查下飞东京的航班是什么时候。
  • A君: 稍等。
    (他低头查看自己的笔记本)
    (牙败!在老王的页面竟然没有任何关于“航班日期”的记录!!!)
  • A君(努力镇定):老王,你应该没告诉过我们关于你飞东京的航班信息啊!
  • 老王(纳尼?!): 我明明昨天就打电话说过了啊!(生气挂断!)

这是怎么一回事?老王在撒谎吗?A君沉思了一秒钟,恍然大悟!——昨天老王的电话是老婆接的——A君马上来到老婆的书桌前翻看她的笔记本。果不其然,老王的航班信息就在上面!随后A君把这次“老王事件”说给了老婆听,她表示也注意到了这个问题……

图片描述

A君一想到这些就抓狂。

第四集:一致性问题成功修复!

自从发现了“一致性”问题后,A君整夜辗转反侧,苦思冥想解决办法。终于在一天清晨,一个绝妙的方案让他想到了!他兴奋地摇醒一旁熟睡的老婆大人,急不可耐地告诉她:

“亲爱的,我想到解决办法了!接下来我们可以这么办:”

  • 从现在开始,我们两人无论谁接到顾客的电话(有信息要求我们记录),我们必须通知对方本次更新信息。
  • 我们要在各自的笔记本上同时记录这次更新信息,才算这个电话close file。
  • 当顾客致电来索要之前存放的信息时,我们无需询问对方,只要查看各自的笔记本就行了。因为我俩的笔记本所记载的顾客信息同一时段时刻保持着同步更新。

“好像还有一个问题!”A君突然意识到。

“这样一来,每次有新的顾客信息“更新”,我们两人都得同时做记录,我们就不能在并行的时间段里接电话了!”

图片描述

“而且,我们无论何时不能给顾客提供错误信息。”A君补充到。

“完全同意”,A君的老婆连连点头,“但是这系统还有另一个缺陷你没注意到。如果哪天我们当中有一个没开工,那就意味着那天所有的‘更新电话’(即:顾客有更新信息要求记录)我们就没能接到,因为没开工的那一方没有更新任何记录。”也就是说,系统还存在“可用性”的问题。

第五集:最完美的解决方案诞生了!

A君渐渐意识到设计一个分布式系统并没有当初预想的那么简单。要同时兼顾“一致性”和“可用性”真的很难做到吗?也许对别人很难,但对于天性骄傲的A君来说,他当然不服输。

这不,几经思索,又一个清晨,一个别人做梦都想不到的完美方案还是让A君想到了,他再次兴冲冲摇醒身旁熟睡的老婆大人。

“看!”,A君兴高采烈,“采用下面这种做法,就能同时实现‘一致性’和‘可用性’了,虽然这做法和之前的很相似”:

  • 从现在开始,我们两人无论谁接到顾客的电话(有信息要求我们记录),如果另一方这天处于开工状态,我们就通知对方本次更新信息。我们要在各自的笔记本上同时记录这次更新信息,才算这个电话close file。
  • 如果另一方这天处于放工状态(放假休息),我们就发电邮通知对方本次更新信息。
  • 第二天另一方收假回来准备开工前,首先得检查所有电邮,把休息这天落下的顾客“更新”信息在自己的笔记本上全部补上。然后再开始这新一天的第一通顾客来电。

“亲爱的,你真是个天才!”A君的老婆拍手称快,“现在我几乎找不出这个系统有任何缺陷了。我们马上开始吧!”于是从这天起,“记忆公司”就能同时做到“一致性”和“可用性”了。

第六集:老婆大人在生气!

一切进行得很顺利。A君的分布式系统不仅完美展示着“一致性”,而且即使哪天他们两人中有一个放假休息,公司运作丝毫无影响。但是有天老婆大人生气了!即使两人都在开工,她接到了顾客要求记录信息的电话,却因为生闷气,决定这一天都不告诉A君“更新“信息。这下完蛋了!到目前为止,一直保持“一致性”和“可用性”的完美系统却因为没有“分区容错性”瞬间崩溃!于是A君决定哄好老婆大人之前,他自己这边不接任何顾客电话,于是在这段时间内,整个系统是失去“可用性”保障的。

图片描述

第七集:总结的时间到了

现在让我们看回CAP理论,它主要是讲,在设计一个分布式系统时,无法同时兼顾“一致性”、“可用性”和“分区容错性”,你只能选择成全其中的两个:

  • 一致性:顾客一旦致电过来,要求记录他的最新信息,那么在他下次索要信息时,都必须第一时间将最新信息准确告诉他,无论顾客回电间隔多么短。
  • 可用性:“记忆公司”一直保持良好的业务运作,即使哪天A君和他老婆中有一个放假休息。
  • 分区容错性:“记忆公司”一直保持良好的业务运作,即使哪天A君和他老婆之间发生冷战,一段时间内拒绝沟通。

最后的彩蛋:招一个跑腿小弟入伙,实现终极“一致性”

如果招一个跑腿小弟入伙,当A君和他老婆其中一方的笔记本有“更新”时,这位小弟可以帮忙跑腿,迅速将他们夫妻中另一方的笔记本同步更新。这样做最大的好处是,他是在后台跑腿,于是接到“更新电话”的一方只要在前端继续进行他的业务即可,无需像之前那样,可能得停下来等待另一方赶来和他“同步”更新笔记本。

很多NoSql系统就是这样工作的,一个节点在本地更新,后端进程将其更新信息同步更新到所有其它节点。唯一的问题是,某些时候系统的“一致性”将得不到保障。

例如,当老婆接到一个顾客电话要求记录信息时,跑腿小弟还没来得及跑过来同步更新A君的笔记本,该顾客一个电话打到A君这里来了,这时他当然不可能得到想要的最新信息……但如果这种情况只是小概率事件的话,招跑腿小弟入伙的想法还是很赞很赞的。你想啊,顾客的记性不会差到前脚“要求记录信息”的电话刚挂断,5分钟后就回电询问“刚记录的信息是什么”吧?!

评论