理論先行-CAP定理
一、分布式系統(tǒng)的需求與困境
是不是會有大佬(產(chǎn)品?老板?)對你所負責(zé)的分布式系統(tǒng)提出以下三點要求:
- 既要:系統(tǒng)高可用
- 又要:各系統(tǒng)數(shù)據(jù)一致且實時可見
- 還要:系統(tǒng)具有集群容錯能力
這些要求看似簡單,但當(dāng)你仔細思考時就會發(fā)現(xiàn)很讓人頭疼、無法全部實現(xiàn);如果你還不理解,我們舉個例子,如防疫時期的靜態(tài)化管理:
- 人停工企業(yè)停產(chǎn)(失去可用性)
- 全城全面核酸,統(tǒng)一采用核酸碼平臺,實時統(tǒng)籌管理數(shù)據(jù)(保證數(shù)據(jù)的一致性)
- 人被限制在小區(qū)內(nèi)活動、交換物資,小區(qū)間禁止互通(分區(qū)容錯)
經(jīng)歷過的人應(yīng)該了解,當(dāng)我們要滿足2、3時,就必須犧牲1;或許你也嘗試思考過如何破局但又困惑無解;不過無需自責(zé),不僅是你會覺得困難,其他人也一樣,因為違背了CAP定理。
二、CAP 定理解惑
在理論計算機科學(xué)中,CAP定理(CAP theorem),又被稱作布魯爾定理(Brewer's theorem),定理討論了兩個互相矛盾的請求,到達彼此連接不通的兩個不同的分布式節(jié)點 的時候的處理方案。
CAP定理 指出對于一個分布式計算系統(tǒng)來說,不可能同時滿足一致性(Consistency)、可用性(Availability)、分區(qū)容錯性(Partition tolerance)。
CAP定理(來自網(wǎng)絡(luò)).png
有這么一種說法:以實際效果而言,系統(tǒng)若不能在時限內(nèi)完成同步,達到數(shù)據(jù)一致性;就意味著發(fā)生了分區(qū)的情況,必須就當(dāng)前操作在一致性和可用性之間做出選擇。
三、一致性(Consistency)
一致性是說,所有節(jié)點訪問同一份最新的數(shù)據(jù)副本;即一致性保證了無論將數(shù)據(jù)寫入哪一個節(jié)點,其它的節(jié)點都能實時同步到這個新數(shù)據(jù),而隨后無論從哪個節(jié)點讀到的都是最新的數(shù)據(jù)。如下圖所示:
CAP定理-一致性(來自網(wǎng)絡(luò)).png
如果節(jié)點之間數(shù)據(jù)同步有異常,那就必須先解決掉同步的問題,掛起所有的請求,等待數(shù)據(jù)同步完成后才響應(yīng),那么會出現(xiàn)以下幾種情況:
- 請求在等待很久后才得到了正確結(jié)果
- 寫入數(shù)據(jù)異常
- 讀取數(shù)據(jù)異常
CAP定理-一致性(來自網(wǎng)絡(luò))?.png
四、可用性(Availability)
可用性是說,如果有節(jié)點異常了,只要向其它無異常的節(jié)點發(fā)送請求,總能正常的收到響應(yīng)數(shù)據(jù),但數(shù)據(jù)可以不是最新的,如下圖所示:
CAP定理-可用性(來自網(wǎng)絡(luò))?.png
五、分區(qū)容錯性(Partition tolerance)
先說分區(qū)是什么,在分布式系統(tǒng)中,不同的節(jié)點分布在不同的子網(wǎng)絡(luò)中,若因一些網(wǎng)絡(luò)故障,出現(xiàn)了子網(wǎng)絡(luò)之間不通的情況,但每個子網(wǎng)絡(luò)內(nèi)是正常的;這樣一個完整的系統(tǒng)就被切分成了若干個相對孤立的區(qū)域,這就是分區(qū)。
對于分布式系統(tǒng)來說,在遇到任何網(wǎng)絡(luò)故障而導(dǎo)致分區(qū)時,仍然能夠?qū)ν馓峁┚哂幸恢滦曰蚩捎眯缘姆?wù)。也就是說會分區(qū)之間即使無法同步數(shù)據(jù),也能對外提供服務(wù)。
CAP定理-分區(qū)容錯性(來自網(wǎng)絡(luò))
六、反推CAP定理
借用一個示例通過反證法來梳理CAP定理,如整個系統(tǒng)由服務(wù)節(jié)點A、B組成,節(jié)點之間通過網(wǎng)絡(luò)通信,當(dāng)節(jié)點 A 進行更新數(shù)據(jù)操作的時候,需要同時更新節(jié)點 B 的數(shù)據(jù)。
集群同步示例(來自網(wǎng)絡(luò))
假設(shè)同時滿足CAP這三個特性,由于具有分區(qū)容錯能力,則可以切斷 A、B兩個節(jié)點間的通信
- 當(dāng)A、B節(jié)點通信斷開后,因無法通信,一致性就無法滿足,但A、B都還能對外提供服務(wù),滿足可用性
- 若要強行滿足一致性,就必須讓A、B節(jié)點不再提供服務(wù),等A、B節(jié)點間的網(wǎng)絡(luò)通信故障修復(fù)后才繼續(xù)提供服務(wù),但這就放棄了可用性。
所以總結(jié)來看:
- 若要一致性:則必須保障節(jié)點間數(shù)據(jù)同步,同步執(zhí)行期間數(shù)據(jù)被鎖定、請求被掛起,會導(dǎo)致請求失敗或超時,破壞了可用性
- 若要可用性:則節(jié)點間數(shù)據(jù)在同步時不允許數(shù)據(jù)被鎖定、請求被掛起,這就破壞了一致性。
七、一致性的取舍
總結(jié)來說,在分布式系統(tǒng)中,首先必須要滿足P,因為是多節(jié)點,一定要會遇到并要容忍分區(qū)錯誤,而C或A則需要根據(jù)具體場景進行取舍。
組合 | 結(jié)果 |
CP | 滿足一致性和分區(qū)容錯性,也就是說,要放棄可用性。當(dāng)系統(tǒng)出現(xiàn)分區(qū),為了保證原子性,必須放棄可用性,讓請求掛起。 |
AP | 滿足可用性和分區(qū)容錯性,當(dāng)出現(xiàn)分區(qū),同時為了保證可用性,即使數(shù)據(jù)尚未完成同步,也必須讓節(jié)點繼續(xù)對外服務(wù),這樣導(dǎo)致數(shù)據(jù)不一致 |
當(dāng)系統(tǒng)既要提供可用性,而又不能放棄一致性的情況下,通常會因場景差異而調(diào)整對一致性的要求,而差異點體現(xiàn)在時效性上如:
- 強一致性
任意時刻,任意節(jié)點都能讀取到最新的數(shù)據(jù) - 弱一致性
可能無法在明確限定的時間內(nèi)讀到最新的數(shù)據(jù) - 最終一致性
是一種弱一致性的特殊形式,系統(tǒng)保證在過了某個時間窗口后,數(shù)據(jù)將達到完全一致的狀態(tài),而之后的讀取到的一定是新數(shù)據(jù)。
分布式業(yè)務(wù)系統(tǒng)實現(xiàn)中,多數(shù)場景中會選擇犧牲一致性來換取可用性。而所謂的犧牲其實就是不追求強一致,而選擇弱一致或最終一致。
本文轉(zhuǎn)載自微信公眾號「架構(gòu)染色」,可以通過以下二維碼關(guān)注。轉(zhuǎn)載本文請聯(lián)系聯(lián)系【架構(gòu)染色】公眾號作者。