對於本地事務處理或者是集中式的事務處理系統,很顯然咱們能夠採用已經被實踐證實很成熟的ACID模型來保證數據的嚴格一致性。而隨着分佈式事務的出現,傳統的單機事務模型已經沒法勝任。尤爲是對於一個高訪問量、高併發的互聯網分佈式系統來講,若是咱們指望實現一套嚴格知足ACID特性的分佈式事務,極可能出現的狀況就是在系統的可用性和嚴格一致性之間出現衝突——由於當咱們要求分佈式系統具備嚴格一致性時,極可能就須要犧牲掉系統的可用性。但毋庸置疑的一點是,可用性又是一個全部消費者不容許咱們討價還價的系統屬性,好比說像淘寶網這樣的在線購物網站,就要求它可以7?24小時不間斷地對外提供服務,而對於一致性,則更加是全部消費者對於一個軟件系統的剛需。所以,在可用性和一致性之間永遠沒法存在一個一箭雙鵰的方案,因而如何構建一個兼顧可用性和一致性的分佈式系統成爲了無數工程師探討的難題,出現了諸如CAP和BASE這樣的分佈式系統經典理論。node
2000年7月,來自加州大學伯克利分校的Eric Brewer教授注 在ACM PODC(Principles of Distributed Computing)會議上,首次提出了著名的CAP猜測。2年後,來自麻省理工學院的Seth Gilbert和Nancy Lynch從理論上證實了Brewer教授CAP猜測的可行性注 ,今後,CAP理論正式在學術上成爲了分佈式計算領域的公認定理,並深深地影響了分佈式計算的發展。mysql
CAP理論告訴咱們,一個分佈式系統不可能同時知足一致性(C:Consistency)、可用性(A:Availability)和分區容錯性(P:Partition tolerance)這三個基本需求,最多隻能同時知足其中的兩項。sql
A read is guaranteed to return the most recent write for a given client.(對某個指定的客戶端來講,讀操做保證可以返回最新的寫操做結果)數據庫
在分佈式環境中,一致性是指數據在多個副本之間是否可以保持一致的特性。在一致性的需求下,當一個系統在數據一致的狀態下執行更新操做後,應該保證系統的數據仍然處於一致的狀態。網絡
對於一個將數據副本分佈在不一樣分佈式節點上的系統來講,若是對第一個節點的數據進行了更新操做而且更新成功後,卻沒有使得第二個節點上的數據獲得相應的更新,因而在對第二個節點的數據進行讀取操做時,獲取的依然是老數據(或稱爲髒數據),這就是典型的分佈式數據不一致狀況。在分佈式系統中,若是可以作到針對一個數據項的更新操做執行成功後,全部的用戶均可以讀取到其最新的值,那麼這樣的系統就被認爲具備強一致性(或嚴格的一致性)。架構
A non-failing node will return a reasonable response within a reasonable amount of time (no error or timeout).(對某個指定的客戶端來講,讀操做保證可以返回最新的寫操做結果)併發
可用性是指系統提供的服務必須一直處於可用的狀態,對於用戶的每個操做請求老是可以在有限的時間內返回結果。這裏咱們重點看下「有限的時間內」和「返回結果」。異步
「有限的時間內」是指,對於用戶的一個操做請求,系統必須可以在指定的時間(即響應時間)內返回對應的處理結果,若是超過了這個時間範圍,那麼系統就被認爲是不可用的。另外,「有限的時間內」是一個在系統設計之初就設定好的系統運行指標,一般不一樣的系統之間會有很大的不一樣。好比說,對於一個在線搜索引擎來講,一般在0.5秒內須要給出用戶搜索關鍵詞對應的檢索結果。以Google爲例,搜索「分佈式」這一關鍵詞,Google可以在0.3秒左右的時間,返回大約上千萬條檢索結果。而對於一個面向HIVE的海量數據查詢平臺來講,正常的一次數據檢索時間可能在20秒到30秒之間,而若是是一個時間跨度較大的數據內容查詢,「有限的時間」有時候甚至會長達幾分鐘。分佈式
從上面的例子中,咱們能夠看出,用戶對於一個系統的請求響應時間的指望值不盡相同。可是,不管系統之間的差別有多大,惟一相同的一點就是對於用戶請求,系統必須存在一個合理的響應時間,不然用戶便會對系統感到失望。高併發
「返回結果」是可用性的另外一個很是重要的指標,它要求系統在完成對用戶請求的處理後,返回一個正常的響應結果。正常的響應結果一般可以明確地反映出對請求的處理結果,即成功或失敗,而不是一個讓用戶感到困惑的返回結果。
讓咱們再來看看上面提到的在線搜索引擎的例子,若是用戶輸入指定的搜索關鍵詞後,返回的結果是一個系統錯誤,一般相似於「OutOfMemoryError」或「System Has Crashed」等提示語,那麼咱們認爲此時系統是不可用的。
The system will continue to function when network partitions occur.(當出現網絡分區後,系統可以繼續「履行職責」)
分區容錯性約束了一個分佈式系統須要具備以下特性:分佈式系統在遇到任何網絡分區故障的時候,仍然須要可以保證對外提供知足一致性和可用性的服務,除非是整個網絡環境都發生了故障。
網絡分區是指在分佈式系統中,不一樣的節點分佈在不一樣的子網絡(機房或異地網絡等)中,因爲一些特殊的緣由致使這些子網絡之間出現網絡不連通的情況,但各個子網絡的內部網絡是正常的,從而致使整個系統的網絡環境被切分紅了若干個孤立的區域。須要注意的是,組成一個分佈式系統的每一個節點的加入與退出均可以看做是一個特殊的網絡分區。
以上就是對CAP定理中一致性、可用性和分區容錯性的講解,一般使用圖1-2所示的示意圖來表示CAP定理。
既然在上文中咱們提到,一個分佈式系統沒法同時知足上述三個需求,而只能知足其中的兩項,所以在進行對CAP定理的應用時,咱們就須要拋棄其中的一項,表1-2所示是拋棄CAP定理中任意一項特性的場景說明。
表1-2.CAP定理應用
|
說明 |
放棄P |
若是但願可以避免系統出現分區容錯性問題,一種較爲簡單的作法是將全部的數據(或者僅僅是那些與事務相關的數據)都放在一個分佈式節點上。這樣的作法雖然沒法100%地保證系統不會出錯,但至少不會碰到因爲網絡分區帶來的負面影響。但同時須要注意的是,放棄P的同時也就意味着放棄了系統的可擴展性。 |
放棄A |
相對於放棄「分區容錯性」來講,放棄可用性則正好相反,其作法是一旦系統遇到網絡分區或其餘故障時,那麼受到影響的服務須要等待必定的時間,所以在等待期間系統沒法對外提供正常的服務,即不可用。 |
放棄C |
這裏所說的放棄一致性,並非徹底不須要數據一致性,若是真是這樣的話,那麼系統的數據都是沒有意義的,整個系統也是沒有價值的。 事實上,放棄一致性指的是放棄數據的強一致性,而保留數據的最終一致性。這樣的系統沒法保證數據保持實時的一致性,可是可以承諾的是,數據最終會達到一個一致的狀態。這就引入了一個時間窗口的概念,具體多久可以達到數據一致取決於系統的設計,主要包括數據副本在不一樣節點之間的複製時間長短。 |
從CAP定理中咱們能夠看出,一個分佈式系統不可能同時知足一致性、可用性和分區容錯性這三個需求。另外一方面,須要明確的一點是,對於一個分佈式系統而言,分區容錯性能夠說是一個最基本的要求。爲何這樣說,其實很簡單,由於既然是一個分佈式系統,那麼分佈式系統中的組件必然須要被部署到不一樣的節點,不然也就無所謂分佈式系統了,所以必然出現子網絡。而對於分佈式系統而言,網絡問題又是一個一定會出現的異常狀況,所以分區容錯性也就成爲了一個分佈式系統必然須要面對和解決的問題。所以系統架構設計師每每須要把精力花在如何根據業務特色在C(一致性)和A(可用性)之間尋求平衡。
BASE是Basically Available(基本可用)、Soft state(軟狀態)和Eventually consistent(最終一致性)三個短語的簡寫,是由來自eBay的架構師Dan Pritchett在其文章BASE: An Acid Alternative注 中第一次明確提出的。BASE是對CAP中一致性和可用性權衡的結果,其來源於對大規模互聯網系統分佈式實踐的總結,是基於CAP定理逐步演化而來的,其核心思想是即便沒法作到強一致性(Strong consistency),但每一個應用均可以根據自身的業務特色,採用適當的方式來使系統達到最終一致性(Eventual consistency)。接下來咱們着重對BASE中的三要素進行詳細講解。
BASE理論是基於CAP定理逐步演化而來的,其核心思想是即便沒法作到強一致性(Strong consistency),但每一個應用均可以根據自身的業務特色,採用適當的方式來使系統達到最終一致性(Eventual consistency)
基本可用是指分佈式系統在出現不可預知故障的時候,容許損失部分可用性——但請注意,這毫不等價於系統不可用。如下兩個就是「基本可用」的典型例子。
響應時間上的損失:正常狀況下,一個在線搜索引擎須要在0.5秒以內返回給用戶相應的查詢結果,但因爲出現故障(好比系統部分機房發生斷電或斷網故障),查詢結果的響應時間增長到了1~2秒。
功能上的損失:正常狀況下,在一個電子商務網站上進行購物,消費者幾乎可以順利地完成每一筆訂單,可是在一些節日大促購物高峯的時候,因爲消費者的購物行爲激增,爲了保護購物系統的穩定性,部分消費者可能會被引導到一個降級頁面。
弱狀態也稱爲軟狀態,和硬狀態相對,是指容許系統中的數據存在中間狀態,並認爲該中間狀態的存在不會影響系統的總體可用性,即容許系統在不一樣節點的數據副本之間進行數據同步的過程存在延時。
分佈式存儲中通常一份數據多個副本,容許不一樣節點間副本同步的延時就是軟狀態的體現。mysql replication的異步複製也是一種體現。
最終一致性強調的是系統中全部的數據副本,在通過一段時間的同步後,最終可以達到一個一致的狀態。所以,最終一致性的本質是須要系統保證最終數據可以達到一致,而不須要實時保證系統數據的強一致性。
亞馬遜首席技術官Werner Vogels在於2008年發表的一篇經典文章Eventually Consistent-Revisited中,對最終一致性進行了很是詳細的介紹。他認爲最終一致性是一種特殊的弱一致性:系統可以保證在沒有其餘新的更新操做的狀況下,數據最終必定可以達到一致的狀態,所以全部客戶端對系統的數據訪問都可以獲取到最新的值。同時,在沒有發生故障的前提下,數據達到一致狀態的時間延遲,取決於網絡延遲、系統負載和數據複製方案設計等因素。
在實際工程實踐中,最終一致性存在如下五類主要變種。
因果一致性是指,若是進程A在更新完某個數據項後通知了進程B,那麼進程B以後對該數據項的訪問都應該可以獲取到進程A更新後的最新值,而且若是進程B要對該數據項進行更新操做的話,務必基於進程A更新後的最新值,即不能發生丟失更新狀況。與此同時,與進程A無因果關係的進程C的數據訪問則沒有這樣的限制。
讀己之所寫是指,進程A更新一個數據項以後,它本身老是可以訪問到更新過的最新值,而不會看到舊值。也就是說,對於單個數據獲取者來講,其讀取到的數據,必定不會比本身上次寫入的值舊。所以,讀己之所寫也能夠看做是一種特殊的因果一致性。
會話一致性將對系統數據的訪問過程框定在了一個會話當中:系統能保證在同一個有效的會話中實現「讀己之所寫」的一致性,也就是說,執行更能操做以後,客戶端可以在同一個會話中始終讀取到該數據項的最新值。
單調讀一致性是指若是一個進程從系統中讀取出一個數據項的某個值後,那麼系統對於該進程後續的任何數據訪問都不該該返回更舊的值。
單調寫一致性是指,一個系統須要可以保證來自同一個進程的寫操做被順序地執行。
在實際系統實踐中,能夠將其中的若干個變種互相結合起來,以構建一個具備最終一致性特性的分佈式系統。事實上,最終一致性並非只有那些大型分佈式系統才涉及的特性,許多現代的關係型數據庫都採用了最終一致性模型。在現代關係型數據庫中,大多都會採用同步和異步方式來實現主備數據複製技術。在同步方式中,數據的複製過程一般是更新事務的一部分,所以在事務完成後,主備數據庫的數據就會達到一致。而在異步方式中,備庫的更新每每會存在延時,這取決於事務日誌在主備數據庫之間傳輸的時間長短,若是傳輸時間過長或者甚至在日誌傳輸過程當中出現異常致使沒法及時將事務應用到備庫上,那麼很顯然,從備庫中讀取的數據將是舊的,所以就出現了數據不一致的狀況。固然,不管是採用屢次重試仍是人爲數據訂正,關係型數據庫仍是可以保證最終數據達到一致——這就是系統提供最終一致性保證的經典案例。
BASE理論面向的是大型高可用可擴展的分佈式系統,和傳統事務的ACID特性是相反的,它徹底不一樣於ACID的強一致性模型,而是提出經過犧牲強一致性來得到可用性,並容許數據在一段時間內是不一致的,但最終達到一致狀態。
但同時,在實際的分佈式場景中,不一樣業務單元和組件對數據一致性的要求是不一樣的,所以在具體的分佈式系統架構設計過程當中,ACID特性與BASE理論每每又會結合在一塊兒使用。