基於 Redis 分佈式鎖:分區分表+兩/三階段提交協議+柔性事務+CAP

基於 Redis 分佈式鎖算法

  1. 獲取鎖的時候,使用 setnx(SETNX key val:當且僅當 key 不存在時,set 一個 key爲 val 的字符串,返回 1;若 key 存在,則什麼都不作,返回 0)加鎖,鎖的 value值爲一個隨機生成的 UUID,在釋放鎖的時候進行判斷。並使用 expire 命令爲鎖添加一個超時時間,超過該時間則自動釋放鎖。數據庫

  2. 獲取鎖的時候調用 setnx,若是返回 0,則該鎖正在被別人使用,返回 1 則成功獲取鎖。 還設置一個獲取的超時時間,若超過這個時間則放棄獲取鎖。服務器

  3. 釋放鎖的時候,經過 UUID 判斷是否是該鎖,如果該鎖,則執行 delete 進行鎖釋放。

分區分表網絡

分庫分表有垂直切分和水平切分兩種。架構

垂直切分(按照功能模塊)異步

將表按照功能模塊、關係密切程度劃分出來,部署到不一樣的庫上。例如,咱們會創建定義數據庫 workDB、商品數據庫 payDB、用戶數據庫 userDB、日誌數據庫 logDB 等,分別用於存儲項目數據定義表、商品定義表、用戶數據表、日誌數據表等。
基於 Redis 分佈式鎖:分區分表+兩/三階段提交協議+柔性事務+CAP
水平切分(按照規則劃分存儲)分佈式

§ 當一個表中的數據量過大時,咱們能夠把該表的數據按照某種規則,例如 userID 散列,進行劃分,而後存儲到多個結構相同的表,和不一樣的庫上。ide

基於 Redis 分佈式鎖:分區分表+兩/三階段提交協議+柔性事務+CAP
兩階段提交協議函數

分佈式事務是指會涉及到操做多個數據庫的事務,在分佈式系統中,各個節點之間在物理上相互獨立,經過網絡進行溝通和協調。XA 就是 X/Open DTP 定義的交易中間件與數據庫之間的接口規範(即接口函數),交易中間件用它來通知數據庫事務的開始、結束以及提交、回滾等。 XA 接口函數由數據庫廠商提供。性能

二階段提交(Two-phaseCommit)是指,在計算機網絡以及數據庫領域內,爲了使基於分佈式系統架構下的全部節點在進行事務提交時保持一致性而設計的一種算法(Algorithm)。一般,二階段提交也被稱爲是一種協議(Protocol))。在分佈式系統中,每一個節點雖然能夠知曉本身的操做時成功或者失敗,卻沒法知道其餘節點的操做的成功或失敗。當一個事務跨越多個節點時,爲了保持事務的 ACID 特性,須要引入一個做爲協調者的組件來統一掌控全部節點(稱做參與者)的操做結果並最終指示這些節點是否要把操做結果進行真正的提交(好比將更新後的數據寫入磁盤等等)。所以,二階段提交的算法思路能夠歸納爲:參與者將操做成敗通知協調者,再由協調者根據全部參與者的反饋情報決定各參與者是否要提交操做仍是停止操做。

準備階段

事務協調者(事務管理器)給每一個參與者(資源管理器)發送 Prepare 消息,每一個參與者要麼直接返回失敗(如權限驗證失敗),要麼在本地執行事務,寫本地的 redo 和 undo 日誌,但不提交,到達一種「萬事俱備,只欠東風」的狀態。

提交階段

若是協調者收到了參與者的失敗消息或者超時,直接給每一個參與者發送回滾(Rollback)消息;不然,發送提交(Commit)消息;參與者根據協調者的指令執行提交或者回滾操做,釋放全部事務處理過程當中使用的鎖資源。(注意:必須在最後階段釋放鎖資源)

缺點

同步阻塞問題

一、執行過程當中,全部參與節點都是事務阻塞型的。

單點故障

二、因爲協調者的重要性,一旦協調者發生故障。參與者會一直阻塞下去。

數據不一致(腦裂問題)

三、在二階段提交的階段二中,當協調者向參與者發送 commit 請求以後,發生了局部網絡異常或者在發送 commit 請求過程當中協調者發生了故障,致使只有一部分參與者接受到了commit 請求。因而整個分佈式系統便出現不數據不一不性的現象(腦裂現象)。

二階段沒法解決的問題(數據狀態不肯定)

四、協調者再發出 commit 消息以後宕機,而惟一接收到這條消息的參與者同時也宕機了。那麼即便協調者經過選舉協議產生了新的協調者,這條事務的狀態也是不肯定的,沒人知道事務是否被已經提交。

三階段提交協議

三階段提交( Three-phase commit ) , 也 叫 三 階 段 提 交 協 議 ( Three-phase commit protocol),是二階段提交(2PC)的改進版本。

與兩階段提交不一樣的是,三階段提交有兩個改動點。

一、引入超時機制。同時在協調者和參與者中都引入超時機制。

二、在第一階段和第二階段中插入一個準備階段。保證了在最後提交階段以前各參與節點的狀態是一致的。也就是說,除了引入超時機制以外,3PC 把 2PC 的準備階段再次一分爲二,這樣三階段

CanCommit 階段

協調者向參與者發送 commit 請求,參與者若是能夠提交就返回 Yes 響應,不然返回 No 響應。

PreCommit 階段

協調者根據參與者的反應狀況來決定是否能夠繼續進行,有如下兩種可能。假如協調者從全部的參與者得到的反饋都是 Yes 響應,那麼就會執行事務的預執行假若有任何一個參與者向協調者發送了 No 響應,或者等待超時以後,協調者都沒有接到參與者的響應,那麼就執行事務的中斷。

doCommit 階段

該階段進行真正的事務提交,主要包含 1.協調這發送提交請求 2.參與者提交事務 3.參與者響應反饋( 事務提交完以後,向協調者發送 Ack 響應。)4.協調者肯定完成事務。

柔性事務

在電商領域等互聯網場景下,傳統的事務在數據庫性能和處理能力上都暴露出了瓶頸。在分佈式領域基於 CAP 理論以及 BASE 理論,有人就提出了 柔性事務 的概念。CAP(一致性、可用性、分區容忍性)理論你們都理解不少次了,這裏再也不敘述。說一下 BASE 理論,它是在 CAP 理論的基礎之上的延伸。包括 基本可用(Basically Available)、柔性狀態(Soft State)、最終一致性(Eventual Consistency)。

一般所說的柔性事務分爲:兩階段型、補償型、異步確保型、最大努力通知型幾種。

兩階段型

一、就是分佈式事務兩階段提交,對應技術上的 XA、JTA/JTS。這是分佈式環境下事務處理的典型模式。

補償型

二、TCC 型事務(Try/Confirm/Cancel)能夠歸爲補償型

WS-BusinessActivity 提供了一種基於補償的 long-running 的事務處理模型。服務器 A 發起事務,服務器 B 參與事務,服務器 A 的事務若是執行順利,那麼事務 A 就先行提交,若是事務 B 也執行順利,則事務 B 也提交,整個事務就算完成。可是若是事務 B 執行失敗,事務 B 自己回滾,這時事務 A 已經被提交,因此須要執行一個補償操做,將已經提交的事務 A 執行的操做做反操做,恢復到未執行前事務 A 的狀態。這樣的 SAGA 事務模型,是犧牲了必定的隔離性和一致性的,可是提升了 long-running 事務的可用性。

基於 Redis 分佈式鎖:分區分表+兩/三階段提交協議+柔性事務+CAP

基於 Redis 分佈式鎖:分區分表+兩/三階段提交協議+柔性事務+CAP
異步確保型

三、經過將一系列同步的事務操做變爲基於消息執行的異步操做, 避免了分佈式事務中的同步阻塞操做的影響。

基於 Redis 分佈式鎖:分區分表+兩/三階段提交協議+柔性事務+CAP
基於 Redis 分佈式鎖:分區分表+兩/三階段提交協議+柔性事務+CAP

最大努力通知型(屢次嘗試)

四、這是分佈式事務中要求最低的一種, 也能夠經過消息中間件實現, 與前面異步確保型操做不一樣的一點是, 在消息由 MQ Server 投遞到消費者以後, 容許在達到最大重試次數以後正常結束事務。

CAP

CAP 原則又稱 CAP 定理,指的是在一個分佈式系統中, Consistency(一致性)、 Availability

(可用性)、Partition tolerance(分區容錯性),三者不可得兼。

一致性(C):

  1. 在分佈式系統中的全部數據備份,在同一時刻是否一樣的值。(等同於全部節點訪問同一份最新的數據副本)

可用性(A):

  1. 在集羣中一部分節點故障後,集羣總體是否還能響應客戶端的讀寫請求。(對數據更新具有高可用性)

分區容忍性(P):

  1. 以實際效果而言,分區至關於對通訊的時限要求。系統若是不能在時限內達成數據一致性,就意味着發生了分區的狀況,必須就當前操做在 C 和 A 之間作出選擇。
相關文章
相關標籤/搜索