http://www.infoq.com/cn/articles/cap-twelve-years-later-how-the-rules-have-changed
傳統(tǒng)數(shù)據(jù)庫堅(jiān)守ACID特性(原子性蜻底、一致性涉茧、隔離性遭赂、持久性)
CAP定理(CAP theorem),又被稱作布魯爾定理(Brewer's theorem)虫蝶,它指出對于一個(gè)分布式計(jì)算系統(tǒng)來說,不可能同時(shí)滿足以下三點(diǎn):
- 一致性(Consistence) (等同于所有節(jié)點(diǎn)訪問同一份最新的數(shù)據(jù)副本)
- 可用性(Availability)(每次請求都能獲取到非錯(cuò)的響應(yīng)——但是不保證獲取的數(shù)據(jù)為最新數(shù)據(jù))
- 分區(qū)容錯(cuò)性(Network partitioning)(以實(shí)際效果而言,分區(qū)相當(dāng)于對通信的時(shí)限要求浆洗。系統(tǒng)如果不能在時(shí)限內(nèi)達(dá)成數(shù)據(jù)一致性,就意味著發(fā)生了分區(qū)的情況嘶摊,必須就當(dāng)前操作在C和A之間做出選擇
根據(jù)定理延蟹,分布式系統(tǒng)只能滿足三項(xiàng)中的兩項(xiàng)而不可能滿足全部三項(xiàng)
。理解CAP理論的最簡單方式是想象兩個(gè)節(jié)點(diǎn)分處分區(qū)兩側(cè)叶堆。允許至少一個(gè)節(jié)點(diǎn)更新狀態(tài)會(huì)導(dǎo)致數(shù)據(jù)不一致阱飘,即喪失了C性質(zhì)。如果為了保證數(shù)據(jù)一致性虱颗,將分區(qū)一側(cè)的節(jié)點(diǎn)設(shè)置為不可用沥匈,那么又喪失了A性質(zhì)。除非兩個(gè)節(jié)點(diǎn)可以互相通信忘渔,才能既保證C又保證A高帖,這又會(huì)導(dǎo)致喪失P性質(zhì)。
1.誤導(dǎo)性
首先畦粮,由于分區(qū)很少發(fā)生棋恼,那么在系統(tǒng)不存在分區(qū)的情況下沒什么理由犧牲C或A。其次锈玉,C與A之間的取舍可以在同一系統(tǒng)內(nèi)以非常細(xì)小的粒度反復(fù)發(fā)生爪飘,而每一次的決策可能因?yàn)榫唧w的操作,乃至因?yàn)闋可娴教囟ǖ臄?shù)據(jù)或用戶而有所不同拉背。最后师崎,這三種性質(zhì)都可以在程度上衡量,并不是非黑即白的有或無椅棺±缯郑可用性顯然是在0%到100%之間連續(xù)變化的,一致性分很多級別两疚,連分區(qū)也可以細(xì)分為不同含義床估,如系統(tǒng)內(nèi)的不同部分對于是否存在分區(qū)可以有不一樣的認(rèn)知。
要探索這些細(xì)微的差別诱渤,就要突破傳統(tǒng)的分區(qū)處理方式丐巫,而這是一項(xiàng)根本性的挑戰(zhàn)。因?yàn)榉謪^(qū)很少出現(xiàn)勺美,CAP在大多數(shù)時(shí)候允許完美的C和A
递胧。但當(dāng)分區(qū)存在或可感知其影響的情況下,就要預(yù)備一種策略去探知分區(qū)并顯式處理其影響赡茸。這樣的策略應(yīng)分為三個(gè)步驟:探知分區(qū)發(fā)生
缎脾,進(jìn)入顯式的分區(qū)模式以限制某些操作,啟動(dòng)恢復(fù)過程以恢復(fù)數(shù)據(jù)一致性并補(bǔ)償分區(qū)期間發(fā)生的錯(cuò)誤占卧。
2.權(quán)衡
怎樣緩和分區(qū)對一致性和可用性的影響是對設(shè)計(jì)師的挑戰(zhàn)遗菠。其關(guān)鍵是以非常明確联喘、公開的方式去管理分區(qū),不僅需要主動(dòng)察覺分區(qū)的發(fā)生辙纬,還需要為分區(qū)期間所有可能受侵害的不變性約束預(yù)備專門的恢復(fù)過程和計(jì)劃耸袜。管理分區(qū)有三個(gè)步驟:
當(dāng)系統(tǒng)進(jìn)入到分區(qū)模式,它有兩種可行的策略牲平。其一是限制部分操作堤框,因此會(huì)削弱可用性。其二是額外記錄一些有利于后面分區(qū)恢復(fù)的操作信息纵柿。系統(tǒng)可通過持續(xù)嘗試恢復(fù)通信來察覺分區(qū)何時(shí)結(jié)束蜈抓。
3.總結(jié)
系統(tǒng)中存在分區(qū),系統(tǒng)設(shè)計(jì)師不應(yīng)該盲目地犧牲一致性或可用性昂儒。設(shè)計(jì)師通過細(xì)致地管理分區(qū)期間的不變性約束沟使,兩方面的性質(zhì)都可以取得最佳的表現(xiàn)。隨著版本向量和CRDTs等比較新的技術(shù)逐漸被納入一些簡化其用法的框架渊跋,這方面的優(yōu)化手段會(huì)得到比較普遍的應(yīng)用腊嗡。但引入CAP實(shí)踐畢竟不像引入ACID事務(wù)那么簡單,實(shí)施的時(shí)候需要對過去的策略進(jìn)行全面的考慮拾酝,最佳的實(shí)施方案極大地依賴于具體服務(wù)的不變性約束和操作細(xì)節(jié)燕少。
案例
自動(dòng)柜員機(jī)上的補(bǔ)償問題
以自動(dòng)柜員機(jī)(ATM)的設(shè)計(jì)來說,強(qiáng)一致性看似符合邏輯的選擇蒿囤,但現(xiàn)實(shí)情況是可用性遠(yuǎn)比一致性重要客们。理由很簡單:高可用性意味著高收入。不管怎么樣材诽,討論如何補(bǔ)償分區(qū)期間被破壞的不變性約束底挫,ATM的設(shè)計(jì)很適合作為例子。
ATM的基本操作是存款脸侥、取款建邓、查看余額。關(guān)鍵的不變性約束是余額應(yīng)大于或等于零睁枕。因?yàn)橹挥腥】畈僮鲿?huì)觸犯這項(xiàng)不變性約束官边,也就只有取款操作將受到特別對待,其他兩種操作隨時(shí)都可以執(zhí)行譬重。
ATM系統(tǒng)設(shè)計(jì)師可以選擇在分區(qū)期間禁止取款操作拒逮,因?yàn)樵谀嵌螘r(shí)間里沒辦法知道真實(shí)的余額,當(dāng)然這樣會(huì)損害可用性⊥喂妫現(xiàn)代ATM的做法正相反,在stand-in模式下(即分區(qū)模式)栅隐,ATM限制凈取款額不得高于k塔嬉,比如k為$200玩徊。低于限額的時(shí)候,取款完全正常谨究;當(dāng)超過限額的時(shí)候恩袱,系統(tǒng)拒絕取款操作。這樣胶哲,ATM成功將可用性限制在一個(gè)合理的水平上畔塔,既允許取款操作,又限制了風(fēng)險(xiǎn)鸯屿。
分區(qū)結(jié)束的時(shí)候澈吨,必須有一些措施來恢復(fù)一致性和補(bǔ)償分區(qū)期間系統(tǒng)所造成的錯(cuò)誤。狀態(tài)的恢復(fù)比較簡單寄摆,因?yàn)椴僮鞫际欠辖粨Q率的谅辣,補(bǔ)償就要分幾種情況去考慮。最后的余額低于零違反了不變性約束婶恼。由于ATM已經(jīng)把錢吐出去了桑阶,錯(cuò)誤成了外部實(shí)在。銀行的補(bǔ)償辦法是收取透支費(fèi)并指望顧客償還勾邦。因?yàn)轱L(fēng)險(xiǎn)已經(jīng)受到限制蚣录,問題并不嚴(yán)重。還有一種情況是分區(qū)期間的某一刻余額已經(jīng)小于零(但ATM不知道)眷篇,此時(shí)一筆存款重新將余額變?yōu)檎陌椤cy行可以追溯產(chǎn)生透支費(fèi),也可以因?yàn)轭櫩鸵呀?jīng)繳付而忽略該違反情況铅歼。
總而言之公壤,因?yàn)橥ㄐ叛舆t的存在,銀行系統(tǒng)不依靠一致性來保證正確性椎椰,而更多地依靠審計(jì)和補(bǔ)償厦幅。“空頭支票詐騙”也是類似的例子慨飘,顧客趕在多家分行對賬之前分別取出錢來然后逃跑确憨。透支的錯(cuò)誤過后才會(huì)被發(fā)現(xiàn),對錯(cuò)誤的補(bǔ)償也許體現(xiàn)為法律行動(dòng)的形式瓤的。