在分佈式系統中,事務每每包含有多個參與者的活動,單個參與者上的活動是可以保證原子性的,而多個參與者之間原子性的保證則須要經過兩階段提交來實現,兩階段提交是分佈式事務實現的關鍵。web
很明顯,兩階段提交保證了分佈式事務的原子性,這些子事務要麼都作,要麼都不作。而數據庫的一致性是由數據庫的完整性約束實現的,持久性則是經過commit日誌來實現的,不是由兩階段提交來保證的。至於兩階段提交如何保證隔離性,能夠參考Large-scale Incremental Processing Using Distributed Transactions and Notifications中兩階段提交的具體實現。算法
兩階段提交的過程涉及到協調者和參與者。協調者能夠看作成事務的發起者,同時也是事務的一個參與者。對於一個分佈式事務來講,一個事務是涉及到多個參與者的。具體的兩階段提交的過程以下:
第一階段:
首先,協調者在自身節點的日誌中寫入一條的日誌記錄,而後全部參與者發送消息prepare T,詢問這些參與者(包括自身),是否可以提交這個事務;
參與者在接受到這個prepare T 消息之後,會根據自身的狀況,進行事務的預處理,若是參與者可以提交該事務,則會將日誌寫入磁盤,並返回給協調者一個ready T信息,同時自身進入可提交狀態;若是不能提交該事務,則記錄日誌,並返回一個not commit T信息給協調者,同時撤銷在自身上所作的數據庫改;
第二階段:
協調者會收集全部參與者的意見。(1)若是收到參與者發來的not commit T信息,則標識着該事務不能提交,協調者會將Abort T 記錄到日誌中,並向全部參與者發送一個Abort T 信息,讓全部參與者撤銷在自身上全部的預操做;(2)若是協調者收到全部參與者發來prepare T信息,那麼協調者會將Commit T日誌寫入磁盤,並向全部參與者發送一個Commit T信息,提交該事務。(3)若協調者遲遲未收到某個參與者發來的信息,則認爲該參與者發送了一個VOTE_ABORT信息,從而取消該事務的執行。
參與者接收到協調者發來的Abort T信息之後,參與者會終止提交,並將Abort T 記錄到日誌中;若是參與者收到的是Commit T信息,則會將事務進行提交,並寫入記錄。數據庫
通常狀況下,兩階段提交機制都能較好的運行,但可能出現下面三種問題: 安全
對於1,當在事務進行過程當中,有參與者宕機時,他重啓之後,能夠經過詢問其餘參與者或者協調者,從而知道這個事務到底提交了沒有。固然,這一切的前提都是各個參與者在進行每一步操做時,都會事先寫入日誌。
對於2,協調者宕機後,能夠起新的協調者,而後查詢全部參與者的狀態是否有commit的,若是有,則繼續commit,若是都沒有,則abort。
對於3,是惟一一個兩階段提交不能解決的困境是:當協調者在發出commit T消息後宕機了,而惟一收到這條命令的一個參與者也宕機了,這個時候這個事務就處於一個未知的狀態,沒有人知道這個事務究竟是提交了仍是未提交,從而須要數據庫管理員的介入,防止數據庫進入一個不一致的狀態。固然,若是有一個前提是:全部節點或者網絡的異常最終都會恢復,那麼這個問題就不存在了,協調者和參與者最終會重啓,其餘節點也最終也會收到commit T的信息。
對於上面的困境,業界提出了三階段提交的方法來此問題,即將二階段提交的第二階段再分爲待定階段(或預提交階段)和肯定階段,從而變爲三階段;在待定階段協調者log prepare_commit消息後向全部參與者發送prepare_commit消息, 待收到全部參與者回包(這裏的回包結果只會成功)或超時時就進入第三段階,log commit消息並向全部參與者發送commit消息。若是在待定階段和肯定階段出現協調者和部分參與者同時宕機(即上面的困境),只要存活的協調者或參與者裏有prepare_commit或commit消息,新的協調者能夠繼續進行commit消息,若是沒有,就不commit消息,從而保證數據的一致性。服務器
二階段提交和三階段提交都是很好的分佈式事務算法,三階段提交是爲解決二階段提交未解決的問題(協調者宕機,參與者也宕機)而提出來的。不過這兩種算法都只考慮一個協調者(主節點)的狀況,沒有考慮多個協調者和如何選出協調者的問題。而另外一種知名分佈式事務算法pasox能解決多個協調者的狀況,並提出了多數派的概念。網絡
Paxos算法是Lamport於1990年提出的一種基於消息傳遞的一致性算法。因爲算法難以理解起初並無引發人們的重視,使Lamport在八年後從新發表到TOCS上。即使如此paxos算法仍是沒有獲得重視,2001年Lamport用可讀性比較強的敘述性語言給出算法描述。可見Lamport對paxos算法情有獨鍾。近幾年paxos算法的廣泛使用也證實它在分佈式一致性算法中的重要地位。06年google的三篇論文初現「雲」的端倪,其中的chubby鎖服務使用paxos做爲chubby cell中的一致性算法,paxos的人氣今後一路狂飆。分佈式
Paxos 算法解決的問題是一個分佈式系統如何就某個值(決議)達成一致。一個典型的場景是,在一個分佈式數據庫系統中,若是各節點的初始狀態一致,每一個節點都執行相同的操做序列,那麼他們最後能獲得一個一致的狀態。爲保證每一個節點執行相同的命令序列,須要在每一條指令上執行一個「一致性算法」以保證每一個節點看到的指令一致,是分佈式計算中的重要問題。學習
安全原則---保證不能作錯的事ui
1. 只能有一個值被批准,不能出現第二個值把第一個覆蓋的狀況google
2. 每一個節點只能學習到已經被批准的值,不能學習沒有被批准的值
存活原則---只要有多數服務器存活而且彼此間能夠通訊最終都要作到的事
1. 最終會批准某個被提議的值
2. 一個值被批准了,其餘服務器最終會學習到這個值
Proposer
提議發起者,處理客戶端請求,將客戶端的請求發送到集羣中,以便決定這個值是否能夠被批准。
Acceptor
提議批准者,負責處理接收到的提議,他們的回覆就是一次投票。會存儲一些狀態來決定是否接收一個值
首先從最簡單的方式開始,假設只有一個Acceptor,多個Proposer,讓它作決定是否批准一個值
每個proposer提議一個值給Acceptor來批准,而後Acceptor批准一個值做爲最終的值。
如何保證一致性?使用互斥(鎖),只有一個proposer可以獲得鎖,一旦值被寫入,後面獲得鎖的proposer沒法改變值。
可是若是某個proposer得到鎖之後,在賦值前down掉了,尚未釋放鎖資源,那麼此時產生了死鎖。
爲了解決死鎖問題,引入了proposer搶佔式,
acceptor可讓某個proposer的訪問失效,再也不接收它的訪問。以後能夠將訪問權發放給其餘proposer。
proposer向acceptor申請訪問權時指定編號epoch(越大越新,可使用當前時間做爲epoch),得到訪問權之後才能向acceptor提交新值。
acceptor採用「喜新厭舊」原則,一旦更大的epoch申請訪問,立刻讓舊的epoch訪問失效,再也不接收他們提交的取值。而後給新的epoch發放訪問權限,接受新的epoch的取值。
新的epoch能夠搶佔舊epoch,讓舊epoch訪問失效,舊epoch的proposer將沒法進行,新epoch的proposer將開始運行。
爲了保證一致性,不一樣epoch的proposer採用「後者認同前者」的原則:
在確定舊epoch沒法生成肯定性取值時,新的epoch會提交本身的value,不會衝突。
一旦舊epoch造成肯定性取值,新的epoch確定能夠得到此取值,而且會認同此取值,不會破壞。
這樣就解決了死鎖問題。
paxos算法就是在搶佔式的基礎上引入多個acceptor,acceptor的實現保持不變,仍採用「喜新厭舊」的原則運行。
paxos採用「少數服從多數「原則,一旦某個epoch的取值f被半數以上的acceptor接受,則認爲確認了f,不能再被更改。
proposer第一階段:
選定epoch,獲取半數以上訪問權,獲取acceptor當前值。
proposer第二階段:
若是得到的當前全部acceptor的值爲null,則將本身的值v提交給全部獲取訪問權的acceptor,若是收到半數以上acceptor成功,則返回成功,不然失敗(acceptor故障或者被新的epoch搶佔)。
若是得到的當前acceptor中有某個有值,則認同其中最大的epoch提交的值f,若是此時f已是半數以上acceptor的值,那麼返回成功。若是不是,則向全部得到訪問權的acceptor提交f。
paxos算法能夠知足容錯需求,半數如下acceptor出現故障時,存活的acceptor仍然能夠生成肯定性取值,一旦取值被肯定,即便半數如下acceptor故障,此取值能夠被獲取,而且將再也不被更改。
在Google的Chubby論文中給出了這樣一種方法:假設有n個proposer,每一個編號爲ir(0<=ir<n),proposor編號的任何值s都應該大於它已知的最大值,而且知足:s %n = ir => s = m*n + ir
proposer已知的最大值來自兩部分:proposer本身對編號自增後的值和接收到acceptor的reject後所獲得的值
以3個proposer P一、P二、P3爲例,開始m=0,編號分別爲0,1,2
1. P1提交的時候發現了P2已經提交,P2編號爲1 > P1的0,所以P1從新計算編號:new P1 = 1*3+0 = 4
2. P3以編號2提交,發現小於P1的4,所以P3從新編號:new P3 = 1*3+2 = 5
1. http://blog.csdn.net/whycold/article/details/47702133
2. http://www.tudou.com/programs/view/e8zM8dAL6hM/
3. http://mp.weixin.qq.com/s?__biz=MjM5MDg2NjIyMA==&mid=203607654&idx=1&sn=bfe71374fbca7ec5adf31bd3500ab95a&key=8ea74966bf01cfb6684dc066454e04bb5194d780db67f87b55480b52800238c2dfae323218ee8645f0c094e607ea7e6f&ascene=1&uin=MjA1MDk3Njk1&devicetype=webwx&version=70000001&pass_ticket=2ivcW%2FcENyzkz%2FGjIaPDdMzzf%2Bberd36%2FR3FYecikmo%3D