技術(shù)大牛談CAP認(rèn)識偏差與選擇假象
關(guān)于CAP原理的討論很多,而且通常會在分布式系統(tǒng)中產(chǎn)生誤解。它規(guī)定:任何連網(wǎng)和分享數(shù)據(jù)的系統(tǒng)最多可以保證以下三個屬性的兩個:一致性、可用性和分區(qū)容錯性。我在此不會詳細(xì)介紹CAP,因為它涉及的方面很多,但是“三個中的兩個”肯定是有誤導(dǎo)性的——雖然概念上很容易理解。Brewer曾經(jīng)指出這個問題,而且認(rèn)同的聲音很多,但是人們對于這個話題仍然存在很多的爭議。底線是你不能犧牲分區(qū)容錯性,但是似乎CAP在這個方面有一些偏差。
表面上,CAP將系統(tǒng)分成了三類。CA表示一個在保持一致性和可用性前提下實現(xiàn)完美可選性的網(wǎng)絡(luò)系統(tǒng)。CP在犧牲一定可用性的前提下實現(xiàn)一致性和分區(qū)容錯性,而AP則不考慮線性一致性的前提下實現(xiàn)可用性和分區(qū)容錯性。顯然,CA暗示系統(tǒng)只有在不存在網(wǎng)絡(luò)分區(qū)時才保證一致性和可用性。然而,要說完全不存在網(wǎng)絡(luò)分區(qū),這顯然是不太現(xiàn)實的。這正是許多爭議發(fā)生的根源。
分區(qū)一定有。它們的出現(xiàn)有很多的原因。交換故障、NIC故障、鏈路層故障、服務(wù)器故障、進(jìn)程故障等,都可能導(dǎo)致分區(qū)出現(xiàn)。即使系統(tǒng)不發(fā)生故障,也有其他原因可能引起分區(qū),例如GC暫?;蜷L時間延遲。我們要先接受這個事實,然后再繼續(xù)分析。這意味著,只有當(dāng)一個“CA”系統(tǒng)變?yōu)椴籆A時,它才是CA的。一旦出現(xiàn)分區(qū),所有假設(shè)和所有保證都會以某一種方式產(chǎn)生嚴(yán)重后果。什么位置不會出現(xiàn)這個問題呢?
CAP的核心在于平衡折衷,但是它是一個排他原則。它告訴我們系統(tǒng)在特定的現(xiàn)實條件下不能做什么?這其中的區(qū)別是并非所有系統(tǒng)都能很好地符合這些模型。如果說Jepsen曾經(jīng)教會我們什么,那么一定是讓我們知道大多數(shù)系統(tǒng)都不符合這些分類,即使當(dāng)初設(shè)計者說是符合的。在實踐中,CAP并不是只有黑白兩面。
Nicolas Liochon最近寫了一系列非常不錯的CAP文章。他很好地解釋了這個既晦澀又容易誤解的術(shù)語(比我解釋得好多了),并且提出了一些非常有意義的觀點。Nicolas認(rèn)為,CA實際上應(yīng)該看作為一種運營范疇的規(guī)范,而CP和AP則是關(guān)于行為的描述。我認(rèn)同這一點,但是我的問題是它回避了一定會出現(xiàn)的平衡折衷。
我們知道網(wǎng)絡(luò)分區(qū)是無法避免的。如果我們給應(yīng)用程序這樣的規(guī)定:“這個應(yīng)用程序不會處理網(wǎng)絡(luò)分區(qū)。如果出現(xiàn)網(wǎng)絡(luò)分區(qū),那么應(yīng)用程序?qū)⒉糠质?,?shù)據(jù)可能受到破壞,而且你可能不得不手工修復(fù)數(shù)據(jù)。”換而言之,我們在這里實際上要求的是CA,但是如果有一個分區(qū)出現(xiàn),那么就可能屬于CP;或者說,很不幸地同時失去了可用性和一致性。
在運營范疇內(nèi),CA實際上意味著當(dāng)出現(xiàn)一個分區(qū)時,系統(tǒng)會攤開雙手并發(fā)出信息:“我拋錨了!”如果我們指定系統(tǒng)不能在網(wǎng)絡(luò)分區(qū)下正常工作,也就是說分區(qū)不在運營范疇之內(nèi)。我們在地球上給一個設(shè)計飛往他拉星球大氣層的太空飛船指定一個規(guī)范有什么意義呢?我們處于一個分區(qū)普遍存在的世界中,因此我們肯定要在運營范疇中支持分區(qū)。CA確定規(guī)定了一個運營范疇,但是你不能將它寫到SLA然后交給客戶看。通俗地說,在沒有定義的時候,它只是一種“未定義行為”模式 ——系統(tǒng)是一致和可用的。CAP并不是一個完美的概念,但是在我看來,它確實很好地強調(diào)了構(gòu)建分布式系統(tǒng)過程中需要考慮的一些基本折衷問題。無論我們有沒有在書面寫下來,它們都存在。如果寫下來了,我們也無法保證可用性。在面對分區(qū)時,CAP似乎只能在一致性和可用性上面二選一。事實上,這里并不是只有兩個選擇。你可以選擇AP、CP或兩者都不選。兩者都不選的問題是,我們很難推出它的原因,甚至很難給它定義。最終,它只是一種選擇假象,因為我們不可能犧牲分區(qū)容錯性。





















