邊看邊聽真舒服,人生短短几個秋...web
![](http://static.javashuo.com/static/loading.gif)
倚天屠龍記中趙敏郡主攜帶一幫高手圍攻武當,武當派掌門張三丰被暗算,傳了一套武功給張無忌用來對付趙敏的手下。這套武功就是太極拳。面試
❝張三丰:無忌,我教你的還記得多少?算法
張無忌:我全忘了!數據庫
張三丰:很好,你只要記住把玄冥二老打趴下就能夠了。微信
![](http://static.javashuo.com/static/loading.gif)
上篇用三國殺
講分佈式中的拜占庭將軍問題,還挺有意思的,此次咱們用倚天屠龍記
中的太極拳
來聊下剩下的三大理論:網絡
-
CAP 理論 -
ACID 理論 -
BASE 理論
❝太極拳的精髓:以柔克剛,剛柔並進,四兩撥千斤,無招勝有招。架構
我把 CAP 理論稱做太極
,ACID 理論稱爲陽
或剛
,BASE 理論稱爲陰
或柔
。ACID 理論追求一致性,BASE 理論原本就叫作柔性事務,追求的是可用性。那張無忌爲何會全忘了還戰勝了玄冥二老呢?由於太極拳的精髓是拳意,無招勝有招。app
一、太極的兩面
CAP 理論是對分佈式系統的特性作了一個高度的抽象,變成了三大指標:編輯器
-
一致性(Consistency) -
可用性(Availability) -
分區容錯性(Partition Tolerance)
分佈式中的一致性,咱們能夠理解爲客戶端的每次讀操做
,無論訪問的是哪一個幾點,要麼讀到的都是同一份最新寫入的數據,要麼讀取失敗。這就很剛了,不能說這種剛
很差,在不少場景中,也確實須要保證高度的一致性。分佈式
爲了幫助你們理解一致性,我舉個倚天屠龍記
的故事:六大派圍攻光明頂。峨眉派
滅絕師太做爲統領,帶領江湖六大派圍攻光明頂
,最開始的進攻策略是從北邊
進攻。滅絕師太發現從北邊進攻不妙,因而飛鴿傳書給武當派
和少林派
從南邊
進攻的命令,可是少林派
的飛鴿被明教輕功絕頂的青翼蝠王韋一笑截獲
了,最後的結果是少林派
從北邊
進攻,武當派
從南邊
進攻,這不就亂套了嗎?以下圖所示:
圍攻光明頂
1.1 理解分佈式中的 CAP
CAP 放到分佈式系統中該如何理解呢?下面舉個例子幫助你們理解。
-
初始環境:客戶端查詢或更新節點 1 和 節點 2,兩個節點存的值 A = 1。
![](http://static.javashuo.com/static/loading.gif)
-
客戶端更新節點 1 中 A 的值,設置 A = 5。
![](http://static.javashuo.com/static/loading.gif)
-
節點 1 將 A 的值更新爲 5 後,返回更新成功給客戶端。
節點 1 返回更新成功 -
客戶端訪問到了節點 2 ,請求獲取 A 的值,結果返回 A = 1。這和節點 1 中存儲的 A 的值就不一致了。
![](http://static.javashuo.com/static/loading.gif)
-
那麼怎麼保證兩個節點中的值都是 A = 5 呢?客戶端將節點 1 更新後,節點 2 也須要更新,才能告訴客戶端更新成功了。
![](http://static.javashuo.com/static/loading.gif)
-
兩個節點都更新成功後,客戶端訪問其中任意一個節點獲取到的都是 A = 5。這個就叫作一致性。
![](http://static.javashuo.com/static/loading.gif)
一致性
強調的是數據正確,每次讀取節點中的數據都是最新寫入的數據。這個我稱做剛
。
可是咱們生產的集羣環境下若是發生分區故障時(節點失聯,節點沒法響應,節點沒法寫入數據),客戶端查詢節點時,咱們不能返回錯誤信息給客戶端。好比說業務集羣中的一些關鍵系統,如註冊中心,不能由於某個節點失聯了,就不響應最新的數據。那麼相關的業務也獲取不到正確的註冊信息而致使系統癱瘓。
可用性
就派上用場了,犧牲數據準確性,每一個節點使用本地數據來響應客戶端的請求。另外當節點不可用時,可使用快速失敗策略,至少不能讓服務長時間不能響應。可用性強調的是服務可用,不保證數據正確。這個我稱做柔
。
以下圖所示:節點 1 和節點 2 返回給客戶端的值分別是 A = 5 和 A = 1,也就是節點 1 和 節點 2 並無保證數據一致性,而是考慮了節點的可用性。
![](http://static.javashuo.com/static/loading.gif)
分區容錯性
的含義就是節點間出現任意數量的消息丟失或高延遲的時候,系統仍然在繼續工做。分佈式系統告訴客戶端,個人內部不論出現什麼樣的數據同步問題,我會一直運行。強調的是集羣堆分區故障的容錯能力。
1.2 CAP 三角
那麼這三個指標又有什麼關係呢?這個就是咱們常常聽到的 CAP
理論。C
表明一致性(Consistency),A
表明可用性(Availability)、P
表明分區容錯性(Partition Tolerance)。
對於分佈式系統,CAP 三個指標只能選擇其中兩個。
-
CA:保證一致性和可用性。當分佈式系統正常運行時(大部分時候所處的狀態),這個時候不須要 P,那麼 C 和 A 可以同時保證。只有在發生分區故障時,才須要 P,這個時候就只能在 C 和 A 之間作出選擇。
典型應用
:單機版部署的 MySQL。 -
CP:保證數據的一致性和分區容錯性,好比配置信息,必須保證每一個節點存的都是最新的,正確的數據。好比 Raft 的強一致性系統,會致使沒法執行讀操做和寫操做。
典型應用
:Etcd、Consul、Hbase。 -
AP:保證分佈式系統的可用性和分區容錯性。用戶訪問系統,都能獲得相應數據,不會出現響應錯誤,可是可能會讀到舊的數據。
典型應用
:Cassandra 和 DynamoDB。
二、太極的剛
2.1 ACID 的剛
最開始知道 ACID 是研究 SQL 數據庫的時候,原子性
(Atomicity)、一致性
(Consistency)、隔離性
(Isolation)、持久性
(Durability)。
這四個屬性是針對事務
而言的,而事務就是爲單個工做單元而執行的一系列操做。如查詢、修改數據、修改數據定義。
事務不只僅只用在數據庫上,還能夠用在業務系統中,好比發券後扣減庫存,這種業務場景能夠定義爲一個事務。單機場景咱們能夠經過加鎖、時間序列等機制來保證單個節點上的 ACID 特性,但沒法保證節點間操做的 ACID 特性。
那麼分佈式系統下該如何解決事務問題呢?這也是面試中常常遇到的題。分佈式事務協議你們必定聽過,好比二階段提交協議
和 TCC 協議
,下面我仍是用六大派圍攻光明頂
故事來說解二階段協議。
2.2 圍攻光明頂
峨眉派
想聚集少林派
、武當派
、崑崙派
明天一塊兒進攻光明頂
。若是有一方不一樣意進攻,或者進攻時機不一致,則須要取消整個行動計劃。少林派、武當派、崑崙派進攻光明頂這一組行動能夠當作是一個分佈式事務
,要麼所有執行、要麼所有不執行。以下圖所示:
![](http://static.javashuo.com/static/loading.gif)
那如何幫助滅絕師太解決這個協同問題?咱們能夠用二階段提交協議來講明。
2.3 二階段提交協議
在二階段提交協議中,滅絕師太先給少林派發送進攻的消息,少林派做爲協調者的身份,由少林派聯繫武當派和崑崙派是進攻仍是撤退。
二階段就是說有兩個階段,1.提交請求階段
(投票階段),2.提交執行階段(完成階段)
。
階段一:提交請求階段:
-
第一步:少林派做爲協調者分別給武當派和崑崙派發送消息: 「明天進攻光明頂,可行?」 -
第二步:少林派、武當派、崑崙派分別評估明天是否能進攻光明頂,若是能,就預留時間並鎖定,再也不安排其餘的進攻事項。 -
第三步:少林派獲得所有的回覆結果,包括少林派本身的評估結果。最後三方的結果都是 可行
。
以下圖所示:
![](http://static.javashuo.com/static/loading.gif)
階段二:提交執行階段:
-
第一步:少林派統計本身、崑崙派和武當派的消息,都是 能夠進攻
,因此能夠執行分佈式事務,進攻光明頂。 -
第二步:少林派通知崑崙派和武當派進攻光明頂。 -
第三步:少林派、崑崙派、武當派召集手下弟子,進攻光明頂(執行事務)。 -
第四步:崑崙派、武當派將 是否已發起進攻
告訴少林派。 -
第五步:少林派彙總本身、崑崙派、武當派的進攻結果給滅絕師太。這樣滅絕師太看到的就是統一的做戰計劃。
![](http://static.javashuo.com/static/loading.gif)
注意:
-
能夠將滅絕師太當作客戶端。少林派、武當派、崑崙派當作分佈式系統的三個節點。少林派做爲協調者。 -
將評估是否能進攻光明頂以及預留時間能夠理解爲須要操做的對象和對象狀態,是否已經準備好了,可否提交新的操做。 -
發送消息、飛鴿傳書能夠理解爲網絡消息。 -
第一個階段中,每一個參與者投票表決事務是放棄仍是提交,一旦投票要求提交事務,那麼就不容許放棄事務。 -
第二個階段中,每一個參與者執行最終統一的決定,提交事務或者放棄事務。這個就是 ACID 的原子性。 -
第一個階段中,須要預留資源,預留期間,其餘人不能操做這個資源。
2.4 二階段協議帶來的問題
ACID 特性是 CAP 中一致性的邊界
,能夠稱做最強的一致性,若是分佈式系統中實現了一致性,必然會影響到可用性
。若是一個節點失敗,這個分佈式事務的執行都是失敗的。
絕大數場景中,對一致性要求沒那麼高,並不須要保證強一致性,短暫的不一致也能接收,最後能保證數據是正確的就OK。也就是說咱們能夠用最終一致性
方案來保證數據的一致性。
另外要提到的就是 TCC
協議(三階段提交協議),他是針對二階段提交中的:協調者故障,參與者長期鎖定資源的痛點
而出的協議。引入了詢問階段和超時機制,減小資源被長時間鎖定。可是須要更多的消息進行協商,增長了系統負載和響應延遲,因此三階段提交協議不多被使用。
三、太極的柔
3.1 BASE 的柔
講了太極的剛,下面來說太極的柔。談到分佈式事務的柔,必定會提到 BASE
理論,俗稱柔性事務
。BASE 理論是 CAP 理論中 AP 的擴展。大部分互聯網分佈式系統都強調可用性,都會考慮引入 BASE 支持。這個理論很是很是重要,我要告訴你的是,掌握了這個理論,設計出符合本身業務的分佈式架構也會變得容易不少,而不是摸不着頭腦。
BASE 的核心:基本可用 BA
(Basically Available)、軟狀態 S
(Soft state)、最終一致性 E
(Eventually consistent)。
那爲何叫它柔性事務?其實它和 ACID 是相對的,不須要保證強一致性,好比一根橡皮筋被拉彎了,你放開橡皮筋後,它就會自行恢復,這個就是橡皮筋柔性的一面。
3.2 BASE 和太極拳有什麼關係
太極拳每一招都不是直直的打出去的,每一招都講求圓滑
、畫弧線
,看起來軟綿綿的,實際上是柔中帶剛。每一招的最後一下都是很是剛硬的抖動一下(這效果我用文字實在描述不出來,你們去看電視吧)。這最後一下就能夠當作是剛的一面,也就是最終一致性。
3.3 基本可用
怎麼理解基本可用?重點是在這個基本,這個理論並無告訴咱們怎麼定義基本,這是一個模糊的概念。其實就是要柔
到什麼程度。
在分佈式系統中,咱們能夠把基本可用理解爲保證核心功能可用,容許損失部分功能的可用性。基本可用
能夠用四種方案來實現。
-
流量削峯:好比多個秒殺場次,某東的 8 點秒殺場,12 點的秒殺場。 -
延遲響應:好比雙 11 期間某商城建立的訂單,會提示客戶訂單正在建立中,可能須要等個十幾秒。 -
體驗降級:好比某次比賽活動,有大量用戶進活動頁查看圖片,這個時候,大量圖片由於網絡超時而沒法顯示,這個時候就能夠考慮替換原有圖片,返回清晰度沒有那麼高或圖片比較小的圖片。 -
過載保護:好比咱們經常使用的消息隊列佔滿了,能夠考慮丟棄後來的請求,或清除隊列中的一些請求,保護系統不過載,但這都須要結合自身的業務場景來設計。
3.4 最終一致性
最終一致性:系統中的全部的數據副本在通過一段時間的同步後,最終可以達到一個一致的狀態。最終能夠理解爲一個短暫的延遲。
最終一致性在很是多的互聯網業務中採用。可是跟錢打交道或金融系統會採用強一致性或事務。
前面提到了 ACID 的強一致性
,而最終一致性
和它是什麼關係?
強一致性其實也是最終一致性的一種。那最終一致性怎麼理解?強一致性能夠看做不存在延遲的一致性。若是沒法容忍延遲就用強一致性,不然就用最終一致性。
3.5 最終一致性和太極拳有什麼關係
太極拳最神奇的一個地方就是卸力
,當對方使出全力攻擊你的時候,用太極的招式將對方使出的力量卸下來,使對方的攻擊無效。卸力能夠和咱們以前講到的流量削峯對應。另外卸完力以後,就是咱們發動攻擊的時候。
四、無招勝有招
回到文章的開頭,張三丰教給張無忌的太極拳,張無忌全忘了,還怎麼能戰勝玄冥二老的呢?
❝由於太極拳重視的是拳意,而不是招式。因此張無忌領會了拳意,無招勝有招。
咱們設計分佈式系統的時候,也不要死記硬背三大理論,要真正懂得原理,而後才能一點一點迭代出最適合當前業務系統的分佈式架構。
五、總結
-
太極拳分爲陰和陽兩方面,就如 CAP 中的 C 和 A。 -
CAP 理論是分佈式中基礎理論,有三個重要指標:一致性、可用性、分區容錯性。 -
ACID 是傳統數據庫的設計理念,追求強一致性。四個指標:原子性、一致性、隔離性、持久性。是 CAP 中 CP 的延伸。 -
BASE 理論是 CAP 中一致性和可用性權衡的結果。是 CAP 中的 AP 的延伸。注重可用性和性能優先,根據業務的場景特色,實現彈性的基本可用,而後實現數據的最終一致性。 -
BASE 理論在很大程度上,解決了事務性系統在性能、容錯、可用性等方面的通病。 -
BASE 理論在 NoSQL 中應用普遍,是 NoSQL 系統設計的事實上的理論支撐。
文中也經過六大派圍攻光明頂的案例給你們講解了二階段提交的核心原理,相信你們必定能看懂。
本篇文章構思 2 周,終於出爐了,悟空不要臉地求個再看和轉發~
- END -
2020-12-11
![](http://static.javashuo.com/static/loading.gif)
![](http://static.javashuo.com/static/loading.gif)
建了學習交流羣,能夠掃碼加我,備註[學習] 一塊兒進階!
本文分享自微信公衆號 - 悟空聊架構(PassJava666)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。