歡迎光臨
每天分享高質量文章

一文讀懂CAP定理

來源:阮一峰的網絡日誌

http://www.ruanyifeng.com/blog/2018/07/cap.html

分佈式系統(distributed system)正變得越來越重要,大型網站幾乎都是分佈式的。

分佈式系統的最大難點,就是各個節點的狀態如何同步。CAP 定理是這方面的基本定理,也是理解分佈式系統的起點。

本文介紹該定理。它其實很好懂,而且是顯而易見的。下麵的內容主要參考了 Michael Whittaker 的文章。

一、分佈式系統的三個指標

1998年,加州大學的計算機科學家 Eric Brewer 提出,分佈式系統有三個指標。

1. Consistency

2. Availability

3. Partition tolerance

它們的第一個字母分別是 C、A、P。

Eric Brewer 說,這三個指標不可能同時做到。這個結論就叫做 CAP 定理。

二、Partition tolerance

先看 Partition tolerance,中文叫做”分割槽容錯“。

大多數分佈式系統都分佈在多個子網絡。每個子網絡就叫做一個區(partition)。分割槽容錯的意思是,區間通信可能失敗。比如,一臺服務器放在中國,另一臺服務器放在美國,這就是兩個區,它們之間可能無法通信。

上圖中,G1 和 G2 是兩台跨區的服務器。G1 向 G2 發送一條訊息,G2 可能無法收到。系統設計的時候,必須考慮到這種情況。

一般來說,分割槽容錯無法避免,因此可以認為 CAP 的 P 總是成立。CAP 定理告訴我們,剩下的 C 和 A 無法同時做到。

三、Consistency

Consistency 中文叫做”一致性“。意思是,寫操作之後的讀操作,必須傳回該值。舉例來說,某條記錄是 v0,用戶向 G1 發起一個寫操作,將其改為 v1。

接下來,用戶的讀操作就會得到 v1。這就叫一致性。

問題是,用戶有可能向 G2 發起讀操作,由於 G2 的值沒有發生變化,因此傳回的是 v0。G1 和 G2 讀操作的結果不一致,這就不滿足一致性了。

為了讓 G2 也能變為 v1,就要在 G1 寫操作的時候,讓 G1 向 G2 發送一條訊息,要求 G2 也改成 v1。

這樣的話,用戶向 G2 發起讀操作,也能得到 v1。

四、Availability

Availability 中文叫做”可用性“,意思是只要收到用戶的請求,服務器就必須給出回應。

用戶可以選擇向 G1 或 G2 發起讀操作。不管是哪台服務器,只要收到請求,就必須告訴用戶,到底是 v0 還是 v1,否則就不滿足可用性。

五、Consistency 和 Availability 的矛盾

一致性和可用性,為什麼不可能同時成立?答案很簡單,因為可能通信失敗(即出現分割槽容錯)。

如果保證 G2 的一致性,那麼 G1 必須在寫操作時,鎖定 G2 的讀操作和寫操作。只有資料同步後,才能重新開放讀寫。鎖定期間,G2 不能讀寫,沒有可用性

如果保證 G2 的可用性,那麼勢必不能鎖定 G2,所以一致性不成立。

綜上所述,G2 無法同時做到一致性和可用性。系統設計時只能選擇一個標的。如果追求一致性,那麼無法保證所有節點的可用性;如果追求所有節點的可用性,那就沒法做到一致性。

[更新 2018.7.17]

讀者問,在什麼場合,可用性高於一致性

舉例來說,發佈一張網頁到 CDN,多個服務器有這張網頁的副本。後來發現一個錯誤,需要更新網頁,這時只能每個服務器都更新一遍。

一般來說,網頁的更新不是特別強調一致性。短時期內,一些用戶拿到老版本,另一些用戶拿到新版本,問題不會特別大。當然,所有人最終都會看到新版本。所以,這個場合就是可用性高於一致性。



編號757,輸入編號直達本文

●輸入m獲取文章目錄

推薦↓↓↓

Web開發

更多推薦18個技術類微信公眾號

涵蓋:程式人生、演算法與資料結構、黑客技術與網絡安全、大資料技術、前端開發、Java、Python、Web開發、安卓開發、iOS開發、C/C++、.NET、Linux、資料庫、運維等。

赞(0)

分享創造快樂