一致性,是指對每一個節點一個數據的更新,整個集羣都知道更新,而且是一致的算法
假設一個具備N個節點的分佈式系統,當其知足如下條件時,咱們說這個系統知足一致性:網絡
假設現實場景中也存在這樣的問題:異步
週五 我:晚上下班吃雞 週六凌晨 xc:好的 // 消息延遲
我:... --------------------------------- 我:晚上下班吃雞 xc:No (兩小時後) xc:No problem! // 宕機節點恢復
我:... --------------------------------- 我:晚上下班吃雞 ... // 節點宕機
--------------------------------- 我:晚上下班吃雞 cx:好,咱們去大保健! // 拜占庭將軍
我:...
2PC(tow phase commit)兩階段提交。分佈式
所謂的兩個階段是指:第一階段:準備階段(投票階段)和第二階段:提交階段(執行階段)。spa
咱們將提議的節點稱爲協調者(coordinator),其餘參與決議節點稱爲參與者(participants, 或cohorts)。3d
在階段1中,協調者發起一個提議,分別問詢各參與者是否接受,以下圖:日誌
在階段2中,協調者根據參與者的反饋,提交或停止事務,若是參與者所有贊成則提交,只要有一個參與者不一樣意就停止。code
以下圖:blog
下面咱們經過一個例子來講明兩階段提交協議的工做過程:事務
A組織B、C和D三我的去登山:若是全部人都贊成去登山,那麼活動將舉行;若是有一人不一樣意去登山,那麼活動將取消。用2PC算法解決該問題的過程以下:
首先A將成爲該活動的協調者,B、C和D將成爲該活動的參與者。
階段1:
①A發郵件給B、C和D,提出下週三去登山,問是否贊成。那麼此時A須要等待B、C和D的郵件。
②B、C和D分別查看本身的日程安排表。B、C發現本身在當日沒有活動安排,則發郵件告訴A它們贊成下週三去登山。因爲某種緣由, D白天沒有查看郵 件。那麼此時A、B和C均須要等待。到晚上的時候,D發現了A的郵件,而後查看日程安排,發現週三當天已經有別的安排,那麼D回覆A說活動取消吧。
階段2:
①此時A收到了全部活動參與者的郵件,而且A發現D下週三不能去登山。那麼A將發郵件通知B、C和D,下週三登山活動取消。
②此時B、C回覆A「太惋惜了」,D回覆A「很差意思」。至此該事務終止。
在異步環境而且沒有節點宕機的模型下,2PC能夠知足全認同、值合法、可結束,是解決一致性問題的一種協議。從協調者接收到一次事務請求、發起提議到事務完成,通過2PC協議後增長了2次RTT(propose+commit),帶來的時延增長相對較少。
二階段提交有幾個缺點:
2PC協議包含協調者和參與者,而且兩者都有發生問題的可能性。假如協調者發生問題,咱們能夠選出另外一個協調者來提交事務。例如,班長組織活動,若是班長生病了,咱們能夠請副班長來組織。若是協調者出問題,那麼事務將不會取消。例如,班級活動但願每一個人都能去,假若有一位同窗不能去了,那麼直接取消活動便可。或者,若是大多數人去的話那麼活動如期舉行(2PC變種)。
三階段提交(Three-phase commit),是二階段提交(2PC)的改進版本。
與兩階段提交不一樣的是,三階段提交有兩個改動點。
也就是說,除了引入超時機制以外,3PC把2PC的準備階段再次一分爲二,這樣三階段提交就有CanCommit
、PreCommit
、DoCommit
三個階段。
3PC的CanCommit階段其實和2PC的準備階段很像。協調者向參與者發送commit請求,參與者若是能夠提交就返回Yes響應,不然返回No響應。
協調者根據參與者的反應狀況來決定是否能夠記性事務的PreCommit操做。根據響應狀況,有如下兩種可能。
假如協調者從全部的參與者得到的反饋都是Yes響應,那麼就會執行事務的預執行。
假若有任何一個參與者向協調者發送了No響應,或者等待超時以後,協調者都沒有接到參與者的響應,那麼就執行事務的中斷。
該階段進行真正的事務提交,也能夠分爲如下兩種狀況。
執行提交
中斷事務
協調者沒有接收到參與者發送的ACK響應(多是接受者發送的不是ACK響應,也可能響應超時),那麼就會執行中斷事務。
相對於2PC,3PC主要解決的單點故障問題,並減小阻塞,由於一旦參與者沒法及時收到來自協調者的信息以後,他會默認執行commit。而不會一直持有事務資源並處於阻塞狀態。可是這種機制也會致使數據一致性問題,由於,因爲網絡緣由,協調者發送的abort響應沒有及時被參與者接收到,那麼參與者在等待超時以後執行了commit操做。這樣就和其餘接到abort命令並執行回滾的參與者之間存在數據不一致的狀況。
在2PC中一個參與者的狀態只有它本身和協調者知曉,假如協調者提議後自身宕機,在協調者備份啓用前一個參與者又宕機,其餘參與者就會進入既不能回滾、又不能強制commit的阻塞狀態,直到參與者宕機恢復。
參與者若是在不一樣階段宕機,咱們來看看3PC如何應對: