天天看點

mysql 分布式 2PC 3pc_2、分布式基礎之一緻性協定、2PC和3PC

一、一緻性問題

一緻性問題:一緻性問題就是互相獨立的節點之間如何達成一項決議的問題。分布式系統中,進行資料庫事務送出(commit transaction)、Leader選舉、序列号生成等都會遇到一緻性問題。

分布式滿足一緻性場景:

假設一個具有N個節點的分布式系統,當其滿足以下條件時,我們說這個系統滿足一緻性:(1)全認同(agreement): 所有N個節點都認同一個結果(2)值合法(validity): 該結果必須由N個節點中的節點提出(3)可結束(termination): 決議過程在一定時間内結束,不會無休止地進行下去.

分布式面臨的問題:

(1)消息傳遞異步無序(asynchronous): 現實網絡不是一個可靠的信道,存在消息延時、丢失,節點間消息傳遞做不到同步有序(synchronous)

(2)節點當機(fail-stop): 節點持續當機,不會恢複

(3)節點當機恢複(fail-recover): 節點當機一段時間後恢複,在分布式系統中最常見

(4)網絡分化(network partition): 網絡鍊路出現問題,将N個節點隔離成多個部分

(5)拜占庭将軍問題(byzantine failure): 節點或當機或邏輯失敗,甚至不按套路出牌抛出幹擾決議的資訊

一緻性還具備兩個屬性,一個是強一緻(safety),它要求所有節點狀态一緻、共進退;一個是可用(liveness),它要求分布式系統247無間斷對外服務。CAP理論中已經說明了,分布式系統不能同時滿足強一緻性和高可用性,應該根據具體的業務做取舍,也就是說在分布式系統進行架構設計的過程中,往往會在可用性和一緻性之間進行反複的權衡,于是産生了一些列的一緻性協定*

二、2PC和3PC

當一個事物操作需要跨越多個分布式節點的時候,為了保持事物處理的ACID特征,需要引入一個“協調者”的元件來統一排程所有分布式節點的執行邏輯,這些被排程的分布式節點稱為“參與者”,協調者負責排程參與者的行為,并最終決定這些參與者是都要把事物真正的送出。基于這個思想,衍生出了二階段送出和三階段送出兩種協定。

1、2PC

2PC:為了使基于分布式系統架構下的所有節點在進行事物處理過程中能夠保持原子性和一緻性而設計的算法。目前絕大數關系型資料庫(比如mysql)都是采用兩階段送出來完成事物處理的。

核心思想:參與者将操作成敗通知協調者,再由協調者根據所有參與者的回報情報決定各參與者是否要送出操作還是中止操作

操作過程:

1、送出事物請求(投票階段):

協調者節點向所有參與者節點詢問是否可以執行送出操作,并開始等待各參與者節點的響應。

參與者節點執行詢問發起為止的所有事務操作,并将Undo資訊和Redo資訊寫入日志。

各參與者節點響應協調者節點發起的詢問。如果參與者節點的事務操作實際執行成功,則它傳回一個”同意”消息;如果參與者節點的事務操作實際執行失敗,則它傳回一個”中止”消息

2、執行事物送出(執行階段):

在該階段,協調者将基于第一個階段的投票結果進行決策:送出或取消。當且僅當所有的參與者同意送出事務協調者才通知所有的參與者送出事務,否則協調者将通知所有的參與者取消事務。參與者在接收到協調者發來的消息後将執行響應的操作。

mysql 分布式 2PC 3pc_2、分布式基礎之一緻性協定、2PC和3PC

兩階段執行流程圖

會産生的問題:

(1)同步阻塞。在兩階段送出的執行過程中,所有的參與者操作的邏輯都是處于阻塞狀态,各個參與者在等待其他參與者響應的過程中,将無法進行其他任何操作。coordinator如果在發起提議後當機,那麼participant将進入阻塞(block)狀态、一直等待coordinator回應以完成該次決議。

(2)單點問題。協調者會有單點問題。

(3)資料不一緻。網絡原因或者其他原因會導緻部分commit部分沒有執行commit,産生資料不一緻。

(4)太過保守。就是說在兩階段中,任意一個節點的失敗都會導緻整個事物失敗。

2、3PC

三階段送出:三階段送出協定在協調者和參與者中都引入逾時機制,并且把兩階段送出協定的第一個階段拆分成了兩步:詢問,然後再鎖資源,最後真正送出。形成canCOmmit、PreCommit、和doCommit三個階段組成的事物處理協定。

mysql 分布式 2PC 3pc_2、分布式基礎之一緻性協定、2PC和3PC

3PC執行流程圖

與2PC比較:(1)相對于2PC,3PC能降低參與者阻塞範圍,主要通過參與者引入逾時機制(在2PC中,隻有協調者擁有逾時機制,即如果在一定時間内沒有收到cohort的消息則預設失敗)(3)2PC的準備階段和送出階段之間,插入預送出階段,使3PC擁有CanCommit、PreCommit、DoCommit三個階段。PreCommit是一個緩沖,保證了在最後送出階段之前各參與節點的狀态是一緻的。(極端情況下面還是會出現不一緻,如果進入PreCommit後,Coordinator發出的是abort請求,假設隻有一個Cohort收到并進行了abort操作,而其他對于系統狀态未知的Cohort會根據3PC選擇繼續Commit,此時系統狀态發生不一緻性。)

3PC如何應對當機:

在階段1中: coordinator或watchdog未收到當機participant的vote,直接中止事務;當機的participant恢複後,讀取logging發現未發出贊成vote,自行中止該次事務

在階段2中: coordinator未收到當機participant的precommit ACK,但因為之前已經收到了當機participant的贊成回報(不然也不會進入到階段2),coordinator進行commit;當機的participant恢複後發現收到precommit或已經發出贊成vote,則自行commit該次事務

在階段3中: 即便coordinator或watchdog未收到當機participant的commit ACK,也結束該次事務;當機的participant恢複後發現收到commit或者precommit,也将自行commit該次事務