eBay的架構師Dan Pritchett源於對大規模分佈式系統的實踐總結,在ACM上發表文章提出BASE理論,BASE理論是對CAP理論的延伸,核心思想是即便沒法作到強一致性(Strong Consistency,CAP的一致性就是強一致性),但應用能夠採用適合的方式達到最終一致性(Eventual Consitency)。 mysql
BASE是指基本可用(Basically Available)、軟狀態( Soft State)、最終一致性( Eventual Consistency)。 sql
電商大促時,爲了應對訪問量激增,部分用戶可能會被引導到降級頁面,服務層也可能只提供降級服務。這就是損失部分可用性的體現。 數據庫
軟狀態是指容許系統存在中間狀態,而該中間狀態不會影響系統總體可用性。分佈式存儲中通常一份數據至少會有三個副本,容許不一樣節點間副本同步的延時就是軟狀態的體現。mysql replication的異步複製也是一種體現。 swift
ACID是傳統數據庫經常使用的設計理念,追求強一致性模型。BASE支持的是大型分佈式系統,提出經過犧牲強一致性得到高可用性。 緩存
ACID和BASE表明了兩種截然相反的設計哲學 網絡
在分佈式系統設計的場景中,系統組件對一致性要求是不一樣的,所以ACID和BASE又會結合使用。 架構
五、NWR是CAP理論的一個具體實踐性的取捨策略: 併發
Amazon寫了個論文,描述了一下若是取捨的具體策略,具體到副本數怎麼設定,這就是NWR。 less
N = 副本數 異步
W = 一次成功的寫操做必須完成的寫副本數
R = 一次成功的讀操做須要讀的副本數(是的,隨便讀一個副本是不行的,你必須讀到必定數量的副本,再相互比較取最新的數據)
策略來講就有具體的公式可供運算,有兩個:
W > N/2
W + R > N
咱們結合Swift的設定,N=3,W=2,R=2(or 1),來看看這兩個公式是什麼意義。
分佈式系統一般用來處理大併發請求的應用,不少請求你們同時來,有一堆在讀,也有一堆想寫。
假設有一個數據擁有三副本,每一個副本已經同步好,原來的值都是A
咱們看看若是不須要知足公式讓W小於3/2,也就是W=1的狀況下會出現什麼問題,W=1,意味着每一個寫的請求只要寫完一個副本便可成功返回。
假設兩個進程同時來更新這份數據,進程W1要把值改寫成C,進程W2要把值改寫成B,那就有可能出現下圖的情形,兩個進程各拿到一個副本改寫,都認爲本身的寫操做是成功的,結果卻留給系統三個不一樣的副本,這樣就出現數據副本不一致的問題。
因此公式W> N/2, 實際上變成了一個寫的鎖,意味着只有寫了過半數副本的纔算寫成功,拿不到的就返回失敗,解決了競爭的問題。以下圖,W1的會話成功,W2的會話就返回失敗。
W> N/2,同時意味着不須要把全部的副本都寫完,未完成的留給系統本身後臺慢慢同步,那這個時候問題就來了,一個新的會話過來讀數據的時候,分配到的副本有多是沒來得及更新的。這時候R1讀回去的就是過期的數據B,而非最新的數據C
第2個公式變形下就是R> N-W,R=2就避免正好倒黴讀到沒更新的那一個。這樣讀回去C和B兩個數據,再比較後取最新的C。因此W+R> N 可以保證每一個讀的請求至少讀到一份最新的數據,
因此你也許已經琢磨出來,這兩個公式更增強調一致性,在可用性上是有所保留的。
固然NWR還可能取其餘值,不一樣的取值表明了不一樣的傾向。若是設定N=3, W=3, R=1,那麼強調的是一致性,寫數據的時候必定要把全部副本都刷新,杜絕中間狀態,這樣一致性獲得很好保證;若是N=3, W=1, R=1,那強調的是可用性,這種狀況下一致性是被犧牲掉了,因此上面兩個保證一致性的公式在這種狀況下就再也不適用。之因此可用性提升是由於讀和寫都放低了要求,只要完成一個副本便可,這樣完成時間下降,響應速度是更快的。
N=3, W=2, R=2是一種折中的策略。其實Amazon的Dynamo就是採用的這個參數,聽說Swift是照搬S3的。
因此回到Swift的副本設定來看,swift的NWR值是可調的,有兩種配置,一種是標準的N3W2R2,可是實際上你也可使用N3W2R1,這個更實用點。在這種配置下,雖然一個數據擁有三副本,可是容錯上讀寫是不同的。網絡斷線,硬盤故障等意外形成一個副本失效時, 系統仍然可讀可寫,但兩個副本失效時,受影響的這部分數據系統就變成只讀,沒法再寫了。
CAP理論和NWR策略在大規模系統下是比較合理的,除了被用來設計分佈式存儲以外,也用來設計分佈式數據庫,好比很熱的NOSQL。另外,這個理論問世已經不短的時間,也常常看到有人發文要挑戰他,也有一些吐槽等等,那個是另外的話題,這裏就再也不繼續了。
六、總結NWR:
R>N/2:表示一次讀操做成功,必須是完成超過半數以上的副本讀操做(否則有可能讀到不一致數據或者出現問題無法根據票數多來進行選舉)
R>N-W:表示一次成功的讀操做,至少要完成超過全部副本數N減去全部寫成功W份數的差值。這樣即能保證每一個讀請求至少可以讀到一份最新數據。
N=3,W=3,R=1:總共副本數爲3,強調了寫的強一致性,寫數據的時候必定要把全部副本刷新才能算寫成功,杜絕中間狀態,這樣一致性達到了很好的保證。
N=3,W=1,R=1:總共副本數爲3,這樣一致性犧牲了,由於讀寫都放低了要求,因此提升了系統可用性。
swift及Amazon採用的默認策略:
N=3, W=2, R=2:這樣保證了每次讀寫必須完成半數以上副本才能算成功,算是折中方案。