首先什麼是一致性? 一致性就是分散式系統中相互獨立多個節點就某個值達成一致。 具體可分為強一致性和弱一致性。 強一致性:在任意時刻,所有節點中的數據是一樣的。同一時間點,你在節點A中獲取到key1的值與在節點B中獲取到key1的值應該都是一樣的。 弱一致性:不保證任意時刻所有節點數據一樣,有很多不同 ...
首先什麼是一致性?
一致性就是分散式系統中相互獨立多個節點就某個值達成一致。
具體可分為強一致性和弱一致性。
強一致性:在任意時刻,所有節點中的數據是一樣的。同一時間點,你在節點A中獲取到key1的值與在節點B中獲取到key1的值應該都是一樣的。
弱一致性:不保證任意時刻所有節點數據一樣,有很多不同實現。最廣泛實現的是最終一致性。所謂最終一致性,就是不保證在任意時刻任意節點上的同一份數據都是相同的,但是隨著時間的遷移,不同節點上的同一份數據總是在向趨同的方向變化。也可以簡單的理解為在一段時間後,節點間的數據會最終達到一致狀態。
分散式一致性的應用場景:
多節點提供讀寫服務,保證高可用性,可伸縮性(ZooKeeper,DNS,redis集群)
分散式系統面臨的問題:
* 消息傳遞非同步無序(asynchronous): 現實網路不是一個可靠的通道,存在消息延時、丟失,節點間消息傳遞做不到同步有序(synchronous)
* 節點宕機(fail-stop): 節點持續宕機,不會恢復
* 節點宕機恢復(fail-recover): 節點宕機一段時間後恢復,在分散式系統中最常見
* 網路分化(network partition): 網路鏈路出現問題,將N個節點隔離成多個部分
* 拜占庭將軍問題(byzantine failure)[2]: 節點或宕機或邏輯失敗,甚至不按套路出牌拋出干擾決議的信息
而需要滿足一致性的分散式系統設計一般前提是無拜占庭將軍問題(內網可信)
此處要提到分散式系統的基礎理論,FLP定理,即當只在節點宕機的模型中,不能同時滿足可用性和強一致性。它的另一個角度提法是CAP理論,即強一致性、可用性和分區容錯性,只能保證其中2個。
保證一致性的協議有很多,包括2PC,3PC,Paxos,raft和PacificA。
2PC:2階段鎖提交協議,保證多個數據分片上操作的原子性。(分散式事務)
節點分為協調者(coordinator)和參與者(participat),執行分為2個階段
階段一:coordinator發起一個提議,分別問詢各participant是否接受。Participate執行事務操作,將undo和redo信息寫入事務日誌,向coordinator回覆yes或no
階段二:coordinator根據participant的反饋,提交或中止事務,如果participant全部yes則提交,只要有一個participant回覆no就中止。Participate根據coordinator的commit/Rollback信息正式提交或終止事務,並釋放占用資源,返回ack。
優點:原理簡單、實現方便
缺點:同步阻塞、單點問題、數據不一致(協調者在未發送完commit請求前崩潰或網路原因部分participate沒收到commit,則部分participate無法進行事務提交)、太過保守(如果參與者在與協調者通信期間出現故障,協調者只能靠超時機制來判斷是否需要中斷事務)
3PC:3階段鎖提交協議,保證多個數據分片上操作的原子性。(分散式事務)
相對2PC,分為詢問,預提交,提交3個階段(解決阻塞,但還是可能數據不一致)
過程:coordinator接收完participant的反饋(vote)之後,進入階段2,給各個participant發送準備提交(prepare to commit)指令。participant接到準備提交指令後可以鎖資源,但要求相關操作必須可回滾。coordinator接收完確認(ACK)後進入階段3、進行commit/abort,3PC的階段3與2PC的階段2無異。協調者備份(coordinator watchdog)、狀態記錄(logging)同樣應用在3PC。
Paxos演算法(解決單點問題)
Paxos演算法是當前最重要的一致性演算法,所有一致性演算法都是paxos或是paxos的簡化版。
Paxos演算法解決多份相同數據就某個值達成一致。正確性證明的理論基礎:任意2個法定集合(超過半數節點組成的集合)的交集不為空。
角色:
從提案到表決流程涉及到三個角色:
* Proposer:提案者,可能有多個,它門負責提出提案。
* Acceptor:接受人,一定要有多個,它們對指定提案進行表決,同意則接受提案,不同意則拒絕。
* Learner:學習人,收集每位Acceptor接受的提案,並根據少數服從多數的原則,形成最終提案。
實際上,分散式系統中一個組件可以對應一種或多種角色。
演算法描述:
* 第一階段(Prepare階段)
Proposer:
* 選取提案編號n,並向大多數Acceptor發送攜帶編號n的prepare請求。
Acceptor:
* 如果收到的提案編號n比自己已經收到的編號都要大,則向Proposer承諾不再接收編號小於n的提案,如果之前接受過提案,則同時將接受的提案中編號最大的提案及其編號發給Proposer。
* 如果收到的提案編號n小於自己已經收到提案編號的最大值,則拒絕。
* 第二階段(Accept階段)
Proposer:
* 首先,對接收到響應,逐條處理:
* 如果接收到拒絕,則暫不處理。
* 如果接收到同意,同時還接收到Acceptor已經接受的提案,則記下該提案及編號。
* 處理完響應後,統計拒絕和同意個數:
* 如果大多數拒絕,則準備下次提案。
* 如果大多數同意,從這些Acceptor已經接受的提案中選取提案編號最大的提案作為自己的提案,沒有則使用自己的提案,逐個向Acceptor發送Accept消息。
Acceptor:
* 如果收到的提案編號n小於自己已經收到最大提案編號,則拒絕。
* 如果收到的提案編號n等於自己已經收到最大提案編號,則接受該提案。
* 如果收到的提案編號n大於自己已經收到最大提案編號,則拒絕。
* 形成共識(與Prepare&Accept階段並行)
Acceptor:
* 每當接受一個提案,則將該提案及編號發給Learner。
Learner:
* 記錄每一個Acceptor當前接受的提案,一個Acceptor先後發來多個提案,則保留編號最大的提案。
* 統計每個提案被接受的Acceptor個數,如果超過半數,則形成共識。
Raft和PacificA是基於paxos的簡化實現,更容易理解更容易實現。等看了再總結下
http://www.cnblogs.com/liulaoshi/p/7821339.html
參考文章:
https://segmentfault.com/a/1190000004474543
https://www.zhihu.com/question/19787937
http://www.cnblogs.com/bangerlee/p/5268485.html
http://www.voidcn.com/article/p-xvyhhccc-dm.html