分佈式一致性問題

引言算法

計算機的系統架構從集中式發展到了分佈式數據庫

集中式特色:整個系統的業務單元都集中部署在一箇中心節點上,數據也集中存儲在這個中心節點上。緩存

集中式的缺點:一旦一臺大型主機出現了故障,那麼整個系統將出於不可用狀態;隨着計算機系統的規模擴大,主機的擴容也比較困難。安全

分佈式的特色:服務器

  分佈性:一個分佈式系統中的計算機在空間部署上是能夠隨意分佈的網絡

  對等性:分佈式系統的計算機沒有主從之分,全部的計算機節點都是對等的,副本是分佈式系統對數據和服務提供的一種冗餘方式,爲了提供高可用服務,一般須要副本。架構

  併發性:一個分佈式系統的多個節點,可能會併發地操做一些共享的資源,如數據庫和分佈式緩存併發

  缺少中心時鐘:在分佈式系統中,很難定義兩個事件究竟誰先誰後,由於缺少一個全局的時鐘序列控制異步

  故障老是會發生:組成分佈式系統的全部計算機,都有可能發生任何形式的故障分佈式

分佈式環境的各類問題

  一、通訊異常:分佈式系統須要各個節點之間進行網絡通訊,所以每次網絡通訊都伴隨着網絡不可用的風險

  二、網絡分區:當網絡發生異常,節點之間的網絡延遲不斷增大,致使只有部分節點之間可以進行正常通訊,另些節點則不能,這種現象叫作網路分區。

    當網絡分區出現時,分佈式系統內會出現局部小集羣,每一個小集羣都有主節點,這種現象稱爲腦裂。

  三、三態:分佈式系統的每一次請求與響應,會存在成功、失敗和超時三種形態

  四、節點故障:組成分佈式系統的節點出現的宕機和僵死現象

 

分佈式事務

  事務的ACID特性和四個隔離級別

  在分佈式數據庫中,數據分散在不一樣的機器上,爲了保證分佈式系統的可靠性,傳統的單機事務模型已經沒法勝任,就須要處理分佈式事務。

  分佈式事務:事務的參與者、支持事務的服務器、資源服務器以及事務管理器分別位於分佈式系統的不一樣節點上,一般一個分佈式事務會涉及多個數據源或者多個業務系統的操做。

CAP和BASE理論:

  對於如何構建一個兼顧可用性和一致性的系統成了一個難題,所以出現了CAP和BASE分佈式系統理論。

CAP理論

  CAP理論告訴咱們,一個分佈式系統不可能同時知足一致性(C:Consistency),可用性(A:Availability)和分區容錯性(P:Partition tolerance)這三個基本需求,最多隻能知足其中的兩項。

  一致性:在分佈式環境中,一致性是指數據在多個副本之間可以保持一致。

  可用性:系統提供的服務必須一直出於可用的狀態,對於用戶的每一次請求老是可以在指定的響應時間內返回一個正常的響應結果

  分區容錯性:分佈式系統在遇到任何網絡分區故障的時候,仍然可以正常對外提供服務,除非整個網絡環境都發生了故障。

當出現網絡分區時,對系統的請求要麼拋棄知足一致性,要麼只更新部分節點知足可用性,所以只能在一致性和可用性中二選一。

對分佈式系統而言,知足分區容錯性是一個最基本的要求。由於在分佈式系統中的各個組件必然須要被部署到不一樣的節點上,各個節點之間必然要進行網絡通訊,而網絡異常又是一個必然會出現的異常狀況,所以分區容錯性是一個分佈式系統必然要面對和解決的問題。所以系統架構師只能在一致性C和可用性A之間尋求平衡。

爲何一致性和可用性只能二選一?

  分佈式系統的節點每每都是分佈在不一樣的機器上進行網絡隔開的,這意味着必然有網絡斷開的風險,這個網絡斷開的場景叫作網絡分區。

  當發生網絡分區時,必然使兩個分佈式節點沒法進行通訊,咱們對一個節點的修改操做將沒法同步到另一個節點,因此數據的一致性將沒法保證,除非咱們犧牲

可用性,對外暫停服務;在網絡分區發生時,再也不提供修改數據的功能,直到網絡情況徹底恢復正常再對外提供服務。

BASE理論:

  BASE是Basically Available(基本可用)、Soft sate(軟狀態)、Eventually consistent(最終一致性)的簡寫。

  BASE是對CAP中一致性和可用性權衡的結果,其來源於對大規模互聯網系統分佈式實踐的總結。基於CAP演化而來,其核心思想是即便沒法作到強一致性(Strong consistency),但每一個應用均可以根據自身業務的特色,採用適當的方式來使系統達到最終一致性。

  BA:基本可用

指分佈式系統在出現不可預知故障的時候,容許損失部分可用性。如:

一、響應時間上的損失:正常狀況下,一個搜索引擎需在0.5秒內返回給用戶相應的響應結果,但因爲故障,好比部分機房發生斷電或斷網故障,響應結果增長到了1~2秒。

二、功能上的損失:如在購物高峯時間段,爲了保證系統穩定性,部分消費者可能會被引導到一個降級頁面

  S:軟狀態

也叫弱狀態,容許分佈式系統在不一樣節點的數據副本之間進行數據同步的過程存在延時。指容許系統中的數據存在中間狀態,並認爲這種中間狀態不會影響系統的總體可用性。

  E:最終一致性

最終一致性強調的是系統中全部的數據副本,在通過一段時間的同步後,最終可以達到一個一致的狀態,而不須要實時保證系統數據的強一致性。

最終一致性是一種特殊的弱一致性:系統可以保證在沒有其餘新的更新操做的狀況下,數據最終必定可以達到一致的狀態,所以全部客戶端對系統的數據訪問都可以獲取到最新的值。

 

  總之,BASE理論面向的是大型高可用可擴展的分佈式系統,和傳統事務的ACID特性是相反的,它徹底不一樣於ACID的強一致性模型,而是提出經過犧牲強一致性來得到可用性

並容許數據在一段時間內是不一致的,但最終達到一致狀態。  在實際的分佈式場景中,不一樣業務單元和組件對數據一致性的要求是不一樣的,所以在具體的分佈式系統架構設計過程當中,

ACID特性與BASE理論每每又會結合在一塊兒使用。

 

分佈式一致性協議和算法

  爲了解決分佈式一致性問題,最著名的就是二階段提交(2PC)協議、三階段提交(3PC)協議和Paxos算法。

  在分佈式系統中,每個機器節點雖然都可以明確知道本身在事務操做過程當中的結果是成功或失敗,但卻沒法直接獲取到其餘分佈式節點的操做結果。(如轉帳,分別調用兩個系統一個減錢,一個加錢,如何保證事務的ACID)。所以當一個事務操做須要跨越多個分佈式節點的時候,爲了保持事務處理的ACID特性,就須要引入第三方「協調者(Coordinator)」(ZK)的組件來統一調度全部分佈式節點的執行邏輯,這些被調度的分佈式節點則被稱爲「參與者(Participant)」。協調者負責調度參與者的行爲,並最終決定這些參與者是否要把事務真正提交。基於這個思想,衍生出了二階段提交和三階段提交協議。

  二階段提交,Two-Phase Commit,2PC ,爲了使基於分佈式系統架構下的全部的節點在進行事務的處理過程當中可以保持原子性和一致性而設計的一種方案。

目前絕大部分的關係型數據庫都是採用二階段提交協議來完成分佈式事物處理的,利用該協議可以很是方便地完成全部分佈式事物參與者的協調,統一決定事務的提交或回滾,從而可以有效地保證分佈式數據一致性。

過程說明:將事務的提交過程分紅了兩個階段來進行處理

階段一:提交事務請求

  一、事務詢問:協調者向全部的參與者發送事務內容,詢問是否能夠執行事務提交操做,並開始等待各參與者的響應

  二、執行事務:各參與者節點執行事務操做,並將Undo和Redo信息記入事務日誌中

  三、各參與者向協調者反饋事務詢問的響應:若是各參與者成功執行了事務操做,那麼就反饋給協調者Yes響應,表示事務能夠執行;若是參與者沒有成功執行事務,那麼就反饋給協調者No響應,

    表示事務不能夠執行

階段二:執行事務提交

  協調者根據階段一中各參與者的反饋狀況來決定是否能夠進行事務提交操做,正常狀況下,包含如下兩種可能:

  一、執行事務提交

  假如協調者從全部的參與者得到的反饋都是Yes響應,那麼就會執行事務提交。

  (1)發送提交請求:協調者向全部參與者節點發出Commit請求

  (2)事務提交:參與者接受到Commit請求後,會正式執行事務提交操做,並在完成提交後釋放整個事務執行期間佔用的事務資源

  (3)反饋事務提交結果:參與者在完成事務提交以後,向協調者發送Ack(ackonwledge  確認)消息

  (4)完成事務:協調者收到全部參與者反饋的Ack消息後,完成事務(?不會出現提交失敗的狀況嗎)

  二、中斷事務

  假如任何一個參與者向協調者反饋了No響應,或者在等待超時以後,協調者尚沒法結構到全部參與者的反饋響應,那麼就會中斷事務

  (1)發送回滾請求:協調者向全部參與者節點發出Rollback請求

  (2)事務回滾:參與者收到Rollback請求後,會利用其在階段一中記錄的Undo信息來執行事務回滾操做,並在完成回滾以後釋放整個事務期間佔用的資源

  (3)反饋事務回滾結果:參與者在完成事務回滾以後,向協調者發出Ack(ackonwledge  確認)消息

  (4)中斷事務:協調者收到全部參與者反饋的Ack消息後完成事務中斷

因此二階段提交的核心就是對每一個事務採用先嚐試後提交的處理方式。

優勢:原理簡單,實現方便

缺點:同步阻塞、單點問題、腦裂、太過保守。

  同步阻塞:在二階段提交的執行過程當中,全部參與該事務操做的邏輯都出於阻塞狀態,也就是說,各個參與者在等待其餘參與者響應的過程當中,將沒法進行其餘任何操做。

  單點問題:協調者出於很是重要的角色,一旦協調者出現問題,特別實在階段二出現問題,那麼其餘參與者將會一直出於鎖定事務資源的狀態中,而沒法繼續完成事務操做。

  數據不一致:若是協調者在向全部的參與者發送Commit請求以後,因爲網絡問題或者協調者還沒有向全部的參與者發送完Commit請求後發生了崩潰,那麼致使只有部分參與者收到了Commit

    請求,因而出現整個分佈式系統數據不一致的狀況。

  太過保守:事務提交詢問過程若是部分參與者故障致使協調者沒法獲取響應信息的話,協調者只能依靠自身超時機制來判斷是否須要中斷事務。即沒有設計較爲完善的容錯機制,任何一個

    節點的失敗都會致使整個事務的失敗

 

  三階段提交,Three-Phase Commit,3PC:在二階段提交協議的基礎上進行了改進。其將二階段提交協議的階段一「提交事務請求」過程一分爲二,造成了由CanCommit、PreCommit和doCommit三個階段組成的事務處理協議。

階段一:CanCommit

  一、事務詢問:協調者向全部的參與者發送一個包含事務內容的CanCommit請求,詢問是否能夠執行事務提交操做,並開始等待各參與者的響應

  二、各參與者向協調者反饋事務詢問的響應:參與者在接受到協調者的CanCommit請求後,評估其自身可否能夠順利執行事務(此時並無執行事務,如嘗試獲取數據庫鎖),那麼反饋Yes響應,

  並進入預備處理狀態,不然反饋No

階段二:PreCommit

  協調者根據各參與者的反饋狀況來決定是否能夠進行事務的PreCommit操做,包含兩種可能:

  一、執行事務預提交

  假如協調者從全部的參與者得到的反饋都是Yes,那麼就會執行事務預提交

    (1)發送預提交請求:協調者向全部的參與者節點發送PreCommit請求

    (2)事務預提交:參與者收到PreCommit請求後,會執行事務操做,並將Undo和Redo信息記錄到事務日誌中

    (3)各參與者向協調者反饋事務執行的響應:若是各參與者成功執行了事務,那麼就會反饋給協調者Ack響應,同時等待最終的指令:提交(commit)或終止(abort),若是在等待

      超時以後仍沒有收到協調者的響應,那麼各參與者都會執行Commit事務提交。

  二、中斷事務

  假如任何一個參與者向協調者反饋了No響應,或者在等待超時以後,協調者尚沒法結構到全部參與者的反饋響應,那麼就會中斷事務

  (1)發送中斷請求:協調者向全部參與者節點發出abort請求

  (2)中斷事務:不管是收到協調者的abort請求或者在等待協調者請求過程當中出現超時,參與者都會中斷事務

階段三:DoCommit

  該階段進行真正的事務提交,存在如下兩種可能狀況:

  一、執行提交

  協調者出於正常工做狀態,而且收到了來自全部參與者的階段二的Ack響應

    (1)發送提交請求:向全部的參與者發送DoCommit請求

    (2)事務提交:參與者收到DoCommit請求後,會正式執行事務提交操做,並在完成提交以後釋放整個事務執行期間佔用的事務資源

    (3)反饋事務提交結果:參與者在完成事務提交以後,向協調者發送Ack消息

    (4)完成事務:協調者接受到全部參與者反饋的Ack消息後,完成事務

  二、中斷事務

  協調者出於正常工做狀態,而且有任意一個參與者向協調者反饋了No響應,或者在等到超時以後,協調者仍沒有收到部分參與者的反饋響應

    (1)發送中斷請求:協調者向全部的參與者節點發送Abort請求

    (2)事務回滾:參與者收到Abort請求後,會利用其在階段二中的Undo信息執行事務回滾操做,並在完成回滾以後釋放在整個事務執行期間佔用的資源

    (3)反饋事務回滾結果:參與者在完成事務回滾以後,向協調者發送Ack消息

    (4)中斷事務:協調者收到全部參與者反饋的Ack消息後,中斷事務

須要注意的是,一旦進入階段三,可能會出現如下兩種故障

  一、協調者出現問題

  二、協調者和參與者之間的網絡出現故障

不管出現哪一種狀況,最終都會致使參與者沒法及時接收到來自協調者的DoCommit或者Abort請求,針對這樣的狀況,參與者都會在等待超時以後,繼續執行事務的提交。

優勢:相比於二階段提交,相對減小了同步阻塞範圍,可以在協調者出現故障以後繼續達成一致(如階段二的超時都執行提交)

缺點:在參與者收到PreCommit消息後,若是網絡出現分區,若是網絡出現分區,部分節點沒法與協調者進行通訊,在超時後仍而後執行事務的提交。若其餘節點在這一階段執行出現問題,協調者發送的是回滾操做,那麼就會出現數據不一致的狀況。

 

  Paxos算法:是一種基於消息傳遞且具備高度容錯特性的一致性算法,是目前公認的解決分佈式一致性問題最有效的算法之一

在常見的分佈式系統中,總會發生網絡分區或節點故障如宕機的狀況,Paxos算法就是在發生上述異常的分佈式系統中,快速且正確地在集羣內部對某個數據的值達成一致,而且保證不論發生以上任何異常,都不會破壞整個系統的一致性。

拜占庭將軍問題:在存在消息丟失的不可靠信道上試圖經過消息傳遞的方式達到一致性是不可能的,所以對一致性的研究通常都假設信道是可靠的(消息不會被篡改),或不存在本問題。

Paxos算法須要解決的問題相似以下的故事場景:

  在古希臘的一個叫作Paxos的小島上,島上採用議會的方式來經過法令,議會中的議員經過信使來進行消息的傳遞,可是議員和信使都是兼職的,他們可能隨時都會離開議會廳(網絡分區),而且信使可能會重複的傳遞消息,也可能會一去不復返(消息丟失);所以議會協議要在這種狀況下法令仍然可以正確的產生,而且不會出現衝突。

Paxos算法詳解

1、問題描述:假設有一組能夠提出提案的節點集合,那麼對一個一致性算法須要保證如下幾點:

  一、在這些被提出的提案中,只有一個會被選定

  二、若是沒有提案被提出,那麼就不會有提案被選定

  三、當一個提案被選定後,節點應該能夠獲取被選定的提案信息

對於一致性來講,安全性需求有如下幾點:

  一、只有被提出的提案才能被選定

  二、只能有一個值被選定

  三、若是某個節點認爲某個提案被選定了,那麼最終被選定的提案就是這個。

Paxos的目標就是要保證最終有一個提案被選定,當提案被選定後,節點最終也能獲取到被選定的提案。

在該一致性算法中,有三種角色,proposer,acceptor和leader,假設不一樣參與者之間能夠經過收發消息來進行通訊,那麼:

  一、每一個參與者以任意的速度執行,可能會出錯而中止,也可能會重啓。同時,即便一個提案被選定後,全部的參與者也都有可能失敗或重啓,所以除非哪些失敗或重啓的參與者可以記錄某些信息,不然將沒法肯定最終的值

  二、消息在傳輸過程當中可能會出現不可預知的延遲,可有可能重複或丟失,但不會被篡改。

 

  proposer提出提案,提案信息包括提案編號和提議的value;

  acceptor收到提案後能夠接受(accept)提案,若提案得到多數派(majority)的acceptors的接受,則該提案被批准(chosn);

  leaders只能學習被批准的提案。

Paxos算法能夠理解成爲了實現某個結果不斷對行爲添加約束而實現的。

算法的約束:

  一、決議(value)只有在proposers提出後才能被批准(未被批准的決議稱爲提案)

  二、在一次Paxos算法的執行實例中,只批准(chosn)一個value(得到多數派的接受),可能批准多個提案,但value相同;

  三、leaders只能得到被批准(chosn)的value。

做者就是不斷增強上面3個約束(主要是第二個)推導了Paxos算法。

推導過程

若在一個提案被提出的狀況下,仍然能夠選出一個提案,那麼就產生了下面這個約束

  P1:一個acceptor必須接受(accept)第一次收到的提案;

注意P1是不完備的,若是剛好一半acceptor接受的提案具備ValueA,另外一半提案具備ValueB,那麼就沒法造成多數派,沒法批准任何一個Value。

約束2並不要求只批准一個提案,暗示可能存在多個提案,只要提案的value相同,則不違反約束2。因而產生了下面的約束:

  P2:一旦一個具備value V的提案被批准(chosn),那麼以後(編號更大的提案)批准(chosn)的提案對應的value必須是value V;

若是P1和P2都能知足,那麼約束2就能保證。

批准一個value意味着多個acceptor接受(accept)了該value,所以可對P2進行細化:

  P2a:一旦一個具備value V的提案被批准,那麼以後任何acceptor再次接受的提案對應的value必須是V;

可是因爲通訊是異步的,P2a和P1可能會產生衝突。如:一個value被批准後,但此時一個proposer和一個acceptor才從休眠中甦醒,前者提出一個具備新的value的提案。根據P1,後者應當接受,根據P2a,則不該當接受,因而在這種場景下,P2a和P1有矛盾。因而換個思路,轉而對Proposer的行爲進行約束:

  P2b:一旦一個具備Value V的提案被批准,那麼以後任何proposer提出的提案對應的值必須是V;

因爲acceptor能接受的提案必須由proposer提出,所以約束P2b包含了P2a,是一個更強的約束。

可是根據P2b難以提出實現手段,所以須要進一步細化P2b;假設一個編號爲m的value V的提案已經得到批准,顯然存在一個acceptors的多數派C,他們都接受了V,又由於其餘任何一個多數派和C至少有一個公共成員;爲了使對任何編號爲n(n>m)的提案對應的Value都爲V,則:

  P2c:若是一個編號爲n的提案對應的value爲V,那麼存在一個多數派,要麼他們中全部人都沒有接受編號小於n的任何提案,要麼他們已經接受的全部編號小於n的提案中編號最大的那個提案對應的value爲V;

用數學概括法可證實P2c包含P2b(假設具備value V的提案m得到批准,當n=m+1時,採用反證法,假如提案n不具備value V,而是具備value W,根據P2c,則存在一個多數派S1,要麼他們中沒有人接受過編號小於n的任何提案,要麼他們已經接受的全部編號小於n的提案中編號最大的那個提案是value W。因爲S1和經過提案m時的多數派C之間至少有一個公共的acceptor,因此以上兩個條件都不成立,導出矛盾從而推翻假設,證實了提案n必須具備value V)。

算法的內容

  要知足P2c的約束,那麼proposer在提出一個提案前,首先要和足以造成多數派的acceptors進行通訊,得到他們進行的最近一次接受(accept)的提案(prepare過程),而後決定此次提案的value,造成提案開始投票。當得到多數acceptors接受後,提案得到批准,由acceptor將這個消息告知leader。這就是Paxos算法的內容。

  若是一個沒有批准過任何proposer提案的acceptor在prepare過程當中回答了一個proposer針對提案n的問題,可是在開始對n進行投票前,又接受了一個編號小於n的另外一個提案,若是n-1和n具備不一樣的value,這個投票就違背P2C。所以在prepare過程當中,acceptor進行的回答也應包含承諾,不會再接受(accept)編號小於n的提案,這是對P1的細化:

  P1a:當且僅當acceptor沒有迴應過編號大於n的prepare請求時,acceptor接受(accept)編號爲n的提案;

 

完整的算法過程:

階段一:prepare階段

  一、proposer選擇一個提案編號n並將prepare請求發送給acceptors中超過半數的acceptor

  二、acceptor收到prepare請求後,若是提案的編號大於它已經回覆(表明accept)的全部prepare消息,則acceptor將本身上次接受的提案回覆給proposer,並承諾再也不接受小於n的提案

階段二:批准(chosn)階段

  一、當一個proposer收到了超半數acceptors對prepare的回覆後,它要向回覆prepare請求的acceptors發送accept請求,包括編號n和P2c決定的value(若是根據P2c沒有已經接受的value,那麼它能夠自由決定value)

  二、在不違背本身向其餘proposer的承諾的前提下,acceptor收到accept請求後即接受這個請求

這個過程在任什麼時候候中斷均可以保證正確性。例如若是一個proposer發現已經有其餘proposers提出了編號更高的提案,則有必要中斷這個過程。所以爲了優化,在上述prepare過程當中,若是一個acceptor發現存在一個更高編號的提案,則須要通知proposer,提醒其中斷此次提案。

 

 Paxos算法的實踐:

Google Chubby是一個面向分佈式系統的鎖服務,一般用於爲一個由大量小型計算機構成的鬆耦合分佈式系統提供分佈式鎖服務。其底層一致性就是以Paxos算法爲基礎的。

相關文章
相關標籤/搜索