在看微服务的时候看到很多关于CAP的讲解,但是感觉都比较理论,不够通俗,看到下面这个以故事形容CAP理论讲的非常好,做个记录
CAP原则。大家都非常清晰的知道:任何的分布式系统,在可用性、一致性和分区容错性方面,是不可兼得的,就像是我们常说的“鱼和熊掌不可兼得”一样,最多值能得其二。所以说,任何一个分布式系统的设计,都是根据各自的实际应用场景和需求,对这三个维度的的不同取舍而已。
CAP原则又称CAP定理,指的是在一个分布式系统中, Consistency(一致性)、 Availability(可用性)、Partition tolerance(分区容错性),三者不可得兼。换句话说,就是说在一个系统中对某个数据不存在一个算法同时满足 Consistency, Availability, Partition-tolerance。
● 一致性(C):在分布式系统中的所有数据备份,在同一时刻是否同样的值。一致性被称为原子对象,任何的读写都应该看起来是“原子“的,或串行的。(等同于所有节点访问同一份最新的数据副本)
● 可用性(A):在集群中一部分节点故障后,集群整体是否还能响应客户端的读写请求。(对数据更新具备高可用性)
● 分区容错性(P):以实际效果而言,分区相当于对通信的时限要求。系统如果不能在时限内达成数据一致性,就意味着发生了分区的情况,必须就当前操作在C和A之间做出选择。
故事下面正式开始:
第一集:商机无处不在——A君的“记忆公司”初诞生!
单体应用的单身
从前有个A君,他好像天生记忆力就特别好。俗话说,健忘是男人的通病,但A君不一样,大到结婚纪念日、老婆大人生日,小到“两人第一次约会纪念日”,“家里的宠物汪生日”,他都能如数家珍。这不,昨晚正是老婆大人生日,他即时送惊喜,哄得老婆大人忒开心。“我的记忆力咋就这么赞呢?”他一阵陶醉……突然,一道灵光闪过,“何不开个公司好好利用这天赋来赚钱?!”而且新公司的广告可以这么打:
A君说做就做,他的“记忆公司”就这样开张了,员工规模嘛,一个人——他自己。
“记忆公司”的日常业务通话是这样的:
顾客:你好,我想存下我老丈人的生日。
A君:请问是什么时候?
顾客:1月2日。
A君:(在笔记本上记下后)当你需要用到它时,欢迎随时致电我们。
顾客:非常感谢。
第二集:是时候扩大规模了!
分布式系统初期
由于A君贴心的服务质量,当然还有他磁性低沉的迷人嗓音,顾客来电络绎不绝。不久后,“记忆公司”就得到某著名创业孵化器的大笔赞助了。你想啊,A君只需要 一个笔记本和一个电话就能开展业务,业务规模当然扩张得很迅速。不知不觉A君每天的电话业务量快破千,这下忙得他焦头烂额。
还有更严重的问题来了。越来越多顾客打电话过来发现永远占线,很多人等得不耐烦就挂断了。再加上A君最近实在太累,终于有天病倒了没有开工,那一整天的业务就这么泡汤了,而对于那天急需信息的顾客来说,不满的情绪更是直线飙升。
是时候扩大公司规模了!A君立刻动员亲爱的老婆大人来帮忙。
而且他设计了一个简单的新系统:
我和老婆一人一部分机。
顾客依然拨打(888)–88-REMEM,他们只需记住这一个号码。
通过一部PBX(电话交换机)将每个顾客来电平等发送到我和老婆两人中正空闲的一部分机上。
第三集:遭遇了第一次服务危机
bug初现
就在新系统上线两天后,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分钟后就回电询问“刚记录的信息是什么”吧?!
再次致敬原作者,太厉害了,通俗易懂
原文地址:http://www.sohu.com/a/7743039...
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。