這篇文章藍本:http://ksat.me/a-plain-english-introduction-to-cap-theorem
經過小碼甲意譯、原創配圖, 干到讓你懷孕。
你可能經常聽到CAP定理, 這個定理描述了在設計分布式系統時的天然約束。 就像其他文章一樣, 本文以現實場景對比理解CAP定理。
1.記憶公司: 單機提供服務
既然大多數人的記憶通常不好,而我擅長記憶,那我就辦一家記憶公司(人肉生活助理)。
記憶公司的日常業務通話記錄:
- 客戶:喂,你好,你可以存儲我鄰居的生日嗎?
- 你: 可以,您說。
- 客戶:1月2號
- 你:記錄(在筆記本這個客戶頁上記下信息), 好的,歡迎下次垂詢。
- 客戶:謝謝
- 你: 請支持1元
2.業務擴張: 分布式服務
創意加人品讓公司越做越大,而成本只有筆記本和電話。
你想要擴張業務,同時你也需要一個兜底。
你有了新計划:
- 你和你老婆分別使用分機
- (555)—55-REMEM 客服電話不變
- 客服電話會轉到空閑的分機號
3.第一次業務出錯: 分布式的數據同步問題
某天你收到老客戶羅**的電話,要求查詢"明天的約會安排";
你一臉蒙蔽,我不知道啊,你的記憶頁上沒這個信息啊;
客戶咣當掛斷了電話。
當天復盤, 猜想是羅志祥昨天把業務電話打到我老婆那里了,事實確實如此。
你們都意識到分機號帶來的新問題。
多么可怕的分布式設計中的缺陷!分布式系統是不一致! 總是會有一個時機,客戶會將業務電話打到你們其中一個;在下一次撥號時,客戶就可能收到不一致的信息。
4.收到數據即時發送: 同步復制
睡前吹風時間, 你想到一個主意:
- 當我們其中一個人接到客戶新的記憶業務,我們會在掛電話之前告訴另一個人
- 這樣我們都能在筆記本上記下新業務
- 當客戶查詢時,我們兩個都可以輕松應對
同步復制帶來2個新問題:
(1)當其中一人收到新業務電話,兩人就不能並行工作了。
例如:當你收到新業務並告訴我記錄信息時, 我不能接其他電話。
但是這個問題也不大,因為大部分都是查詢業務(可以再撥電話重試),我們首要的是確保信息正確。
(2)我收到新業務,而你不在崗,我就不能掛斷電話完成這單業務, 這就帶來可用性問題。**
5. 異步復制
你慢慢理解了分布式系統中的“一致性”和“可用性”。
- 收到新業務電話, 掛電話前通知對方,這樣兩個人都能記下信息
- 某天其中一人不在崗,另外一人收到新業務 ,給欠崗者發一封郵件
- 第二天缺崗者上崗查收郵件,更新自己的筆記本。
Nice, 現在一致性和可用性都滿足了。
6. 老婆難養 : 發生網絡分區
但是, 凡是都有但是, 某天你們都在崗,但是你老婆嫌你碗沒洗干凈,今兒不想理你,收到新業務不通知你了(你們之間的聯系斷開了**)*。
你的方案包含了“一致性”,“可用性”, 但是不滿足“分區容錯”。
為了滿足“分區容錯”,你可以自我下線(直到你們修復關系),讓你老婆一人接手業務,但是你的系統就不可用了。
7.結論
我們回過頭看CAP定理: 在設計分布式系統時,“一致性Consistency
”“可用性Availability”“分區容錯Partition Tolerance” 你只能滿足兩個。
- Consistency:一旦接受了客戶的新業務,在客戶后續查詢時必須得到最新的信息
- Availability:只要你們一人在崗,記憶公司就一直提供服務 (內部節點下線的角度)
- Partition Tolerance:你們夫妻二人鬧矛盾了,記憶公司依舊服務 (節點連通性角度)
雇佣工具人-->最終一致性
雇佣工具人,更新[未更新的人]的筆記本,相比你老婆實時通知你更新, 這個工具人有個好處是在后台跑腿,你們兩個業務都不會阻塞。
這也是很多NoSql的工作方式:一個節點在本地更新,后台進程同步到其他節點, 唯一存在的問題是少數時候丟失一致性。
你老婆收到新業務,工具人還沒來得及跑腿,客戶就理解回撥並轉到你的分機,你給出不一致的答復。這種情況有限,因為客戶不會如此迅速忘記事情。
這就是CAP定理和最終一致性的 現實解釋。****