The Byzantine Generals Problem
問題描述
參考維基百科:拜占庭將軍問題
投票
Situation1
A:1,B:1,C:0
A收到的指令1和0的比例爲:2:1
B收到的指令1和0的比例爲:2:1
C收到的指令1和0的比例爲:2:1
投票結果執行1指令
Situation2
A:0,B:1,C:0
A收到的指令1和0的比例爲:1:2
B收到的指令1和0的比例爲:1:2
C收到的指令1和0的比例爲:1:2
投票結果執行0指令
Situation3
A:0,B:1/0,C:1
A收到的指令1和0的比例爲:2:1
B(故障節點)
C收到的指令1和0的比例爲:1:2
投票結果A執行1指令,C執行0指令,產生了不一致
解決辦法一:口信消息型拜占庭問題之解
- TODO
加密簽名防篡改版
Situation4
A:1,B:BAD,C:1
A:執行1指令
B:bad節點
C:執行1指令(發現被篡改指令,執行A指令)、
投票結果執行1指令,
Situation4
B:BAD,A,0,C:1
A,C: 發現來自B的信息不一致,被篡改,刪除B並重新投票.
CAP
在分佈式系統中由於分佈式的特性和網絡延遲和故障的存在以及在不同業務情況下的不同要求等等。。於是催生了CAP的概念。
CAP?
-
Consistency: 表示分佈式系統中的一致性,在客戶端訪問分佈式系統中的不同節點時要麼返回相同的返回值,要麼不返回數據。
-
Availability: 表示可用性,在分佈式系統中如果出現不同節點間的數據不一致的情況,爲了保證不會出現不返回數據的情況,各個節點返回的數據可能會不一致。但重在每個節點都能返回數據。
-
Partition Tolerance: 分區容錯性旨在保證系統的容錯能力,在不同節點間可能會出現各種故障,爲了保證不管系統內部出現什麼問題,任然保證系統能夠繼續提供服務。
示意圖
CAP 不可能三角
對於一個分佈式系統而言,這三個指標是不可兼得的,在CA兩者之間必須根據實際的業務特點選擇一個。在任何系統中P這個指標是必須選擇的,因爲無論如何都要保證系統不能掛掉,否則無論什麼選擇都將毫無意義。
CP組合
如果選擇了C意味着如果因爲節點間消息丟失,網絡延遲導致分區時,部分節點可能無法保證數據最新時,集羣中就會出現拒絕寫請求。
AP組合,在選擇了A的時候,系統將會以響應客戶請求爲主,如果發生了節點間故障,即使無法返回最新的數據,各個節點也會把當前系統最新值返回給客戶端.
CP模型的典型:ZooKeeper, Etcd和Hbase
AP: …
TPC
two phrase commit: 兩階段提交,在分佈式環境中爲了保證數據一致性C(Consistency),TPC產生了,其將事務的完全提交分爲兩個階段:
- prepare階段
- commit階段
過程解析
-
Client 發送變更請求到TC,Transaction Coordinator 在這裏扮演着leader的職責,負責收集各個節點的響應和下達命令到各個節點。
-
TC 通知各個業務節點進入prepare階段(兩階段提交中的第一階段)
-
業務節點判斷是否可以正常執行業務,並返回判斷結果給TC.
-
TC收集各個節點的判斷結果,並根據最終結果發出rollback還是commit的指令給各個節點進行確認parepare的準備工作(兩階段提交中的第二階段).
prepare階段要求節點的變更是持久化的,不論在tc和服務節點之中任何節點出現了問題,都要求在被修復後的節點可以通過持久化的記錄來使業務數據保證一致的狀態。
TC的第二階段指令也需要持久化,在發生節點發生故障時,修復後可以通過詢問tc服務節點獲取最終應該執行的指令以保證服務的一致性。
在第四步中如果有任何一個節點的prepare返回的是no,tc都會下發rollback指令,
由於在第一階段和第二階段之間還會產生數次通信,存在延時鎖定資源的弊端,爲了解決這個問題,就出現了TCC
TCC(Try-Confirm-Cancel)
Try、Confirm、Cancel 包含了兩個階段Try和Confirm或者Cancel。
同理tcc也是爲了保證節點間的數據具有一致性,舉例說明其實現原理:
網上購物場景,假設設計的場景有:訂單服務(更新訂單狀態)、庫存服務(減庫存)、積分服務(增加積分)
正常工作流程如下:
爲了保證以上這些服務能夠保持數據的一致性,這些節點要麼全部成功,要麼全部失敗。如果在上述途中發生了庫存服務不足的情況,就需要庫存服務通知其他服務來回滾剛纔操作,這裏開始引入TCC
TCC
Try:
在無法確認所有服務都能完成正常操作之前,先將需要使用到的資源進行預留操作,如下所示:
T階段:
在這一步不會先把所有的操作都落庫,只是先對資源進行一次凍結
Confirm:
在上一階段,如果所有的服務都能成功凍結資源,也就相當於確保了所有的服務都能正常處理這部分業務。獲得了凍結成功的信息,可以通知各個服務將凍結資源和實際資源進行merge,完成確認操作。
Cancel:
如果在T階段有服務無法完成資源的凍結操作,如下所示:
在得知store service無法完成扣將庫存操作時,按照tcc機制,要求通知所有服務回滾T操作
在感知各個服務能否正常工作時,需要提供專門的TCC框架,可以自己寫(如果有能力),一般會引入現有一些開源框架,例如: yteTCC,TCC-transaction,Himly等等…