亚洲视频二区_亚洲欧洲日本天天堂在线观看_日韩一区二区在线观看_中文字幕不卡一区

公告:魔扣目錄網為廣大站長提供免費收錄網站服務,提交前請做好本站友鏈:【 網站目錄:http://www.430618.com 】, 免友鏈快審服務(50元/站),

點擊這里在線咨詢客服
新站提交
  • 網站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747


好文推薦:微服務架構下的分布式事務基礎入門

眾所周知,數據庫能實現本地事務,也就是在同一個數據庫中,你可以允許一組操作要么全都正確執行,要么全都不執行。這里特別強調了本地事務,也就是目前的數據庫只能支持同一個數據庫中的事務。但現在的系統往往采用微服務架構,業務系統擁有獨立的數據庫,因此就出現了跨多個數據庫的事務需求,這種事務即為“分布式事務”。那么在目前數據庫不支持跨庫事務的情況下,我們應該如何實現分布式事務呢?本文首先會為大家梳理分布式事務的基本概念和理論基礎,然后介紹幾種目前常用的分布式事務解決方案。廢話不多說,那就開始吧~

1. 什么是事務?

事務由一組操作構成,我們希望這組操作能夠全部正確執行,如果這一組操作中的任意一個步驟發生錯誤,那么就需要回滾之前已經完成的操作。也就是同一個事務中的所有操作,要么全都正確執行,要么全都不要執行。

2. 事務的四大特性 ACID

說到事務,就不得不提一下事務著名的四大特性。

  • 原子性
  • 原子性要求,事務是一個不可分割的執行單元,事務中的所有操作要么全都執行,要么全都不執行。
  • 一致性
  • 一致性要求,事務在開始前和結束后,數據庫的完整性約束沒有被破壞。
  • 隔離性
  • 事務的執行是相互獨立的,它們不會相互干擾,一個事務不會看到另一個正在運行過程中的事務的數據。
  • 持久性
  • 持久性要求,一個事務完成之后,事務的執行結果必須是持久化保存的。即使數據庫發生崩潰,在數據庫恢復后事務提交的結果仍然不會丟失。
注意:事務只能保證數據庫的高可靠性,即數據庫本身發生問題后,事務提交后的數據仍然能恢復;而如果不是數據庫本身的故障,如硬盤損壞了,那么事務提交的數據可能就丟失了。這屬于『高可用性』的范疇。因此,事務只能保證數據庫的『高可靠性』,而『高可用性』需要整個系統共同配合實現。

3. 事務的隔離級別

這里擴展一下,對事務的隔離性做一個詳細的解釋。

在事務的四大特性ACID中,要求的隔離性是一種嚴格意義上的隔離,也就是多個事務是串行執行的,彼此之間不會受到任何干擾。這確實能夠完全保證數據的安全性,但在實際業務系統中,這種方式性能不高。因此,數據庫定義了四種隔離級別,隔離級別和數據庫的性能是呈反比的,隔離級別越低,數據庫性能越高,而隔離級別越高,數據庫性能越差。

3.1 事務并發執行會出現的問題

我們先來看一下在不同的隔離級別下,數據庫可能會出現的問題:

  1. 更新丟失
  2. 當有兩個并發執行的事務,更新同一行數據,那么有可能一個事務會把另一個事務的更新覆蓋掉。
  3. 當數據庫沒有加任何鎖操作的情況下會發生。
  4. 臟讀
  5. 一個事務讀到另一個尚未提交的事務中的數據。
  6. 該數據可能會被回滾從而失效。
  7. 如果第一個事務拿著失效的數據去處理那就發生錯誤了。
  8. 不可重復讀
  9. 不可重復度的含義:一個事務對同一行數據讀了兩次,卻得到了不同的結果。它具體分為如下兩種情況:
  • 虛讀:在事務1兩次讀取同一記錄的過程中,事務2對該記錄進行了修改,從而事務1第二次讀到了不一樣的記錄。
  • 幻讀:事務1在兩次查詢的過程中,事務2對該表進行了插入、刪除操作,從而事務1第二次查詢的結果發生了變化。
不可重復讀 與 臟讀 的區別? 臟讀讀到的是尚未提交的數據,而不可重復讀讀到的是已經提交的數據,只不過在兩次讀的過程中數據被另一個事務改過了。

3.2 數據庫的四種隔離級別

數據庫一共有如下四種隔離級別:

  1. Read uncommitted 讀未提交
  2. 在該級別下,一個事務對一行數據修改的過程中,不允許另一個事務對該行數據進行修改,但允許另一個事務對該行數據讀。
  3. 因此本級別下,不會出現更新丟失,但會出現臟讀、不可重復讀。
  4. Read committed 讀提交
  5. 在該級別下,未提交的寫事務不允許其他事務訪問該行,因此不會出現臟讀;但是讀取數據的事務允許其他事務的訪問該行數據,因此會出現不可重復讀的情況。
  6. Repeatable read 重復讀
  7. 在該級別下,讀事務禁止寫事務,但允許讀事務,因此不會出現同一事務兩次讀到不同的數據的情況(不可重復讀),且寫事務禁止其他一切事務。
  8. Serializable 序列化
  9. 該級別要求所有事務都必須串行執行,因此能避免一切因并發引起的問題,但效率很低。

隔離級別越高,越能保證數據的完整性和一致性,但是對并發性能的影響也越大。對于多數應用程序,可以優先考慮把數據庫系統的隔離級別設為Read Committed。它能夠避免臟讀取,而且具有較好的并發性能。盡管它會導致不可重復讀、幻讀和第二類丟失更新這些并發問題,在可能出現這類問題的個別場合,可以由應用程序采用悲觀鎖或樂觀鎖來控制。

4. 什么是分布式事務?

到此為止,所介紹的事務都是基于單數據庫的本地事務,目前的數據庫僅支持單庫事務,并不支持跨庫事務。而隨著微服務架構的普及,一個大型業務系統往往由若干個子系統構成,這些子系統又擁有各自獨立的數據庫。往往一個業務流程需要由多個子系統共同完成,而且這些操作可能需要在一個事務中完成。在微服務系統中,這些業務場景是普遍存在的。此時,我們就需要在數據庫之上通過某種手段,實現支持跨數據庫的事務支持,這也就是大家常說的“分布式事務”。

這里舉一個分布式事務的典型例子——用戶下單過程。

當我們的系統采用了微服務架構后,一個電商系統往往被拆分成如下幾個子系統:商品系統、訂單系統、支付系統、積分系統等。整個下單的過程如下:

  1. 用戶通過商品系統瀏覽商品,他看中了某一項商品,便點擊下單
  2. 此時訂單系統會生成一條訂單
  3. 訂單創建成功后,支付系統提供支付功能
  4. 當支付完成后,由積分系統為該用戶增加積分

上述步驟2、3、4需要在一個事務中完成。對于傳統單體應用而言,實現事務非常簡單,只需將這三個步驟放在一個方法A中,再用Spring的@Transactional注解標識該方法即可。Spring通過數據庫的事務支持,保證這些步驟要么全都執行完成,要么全都不執行。但在這個微服務架構中,這三個步驟涉及三個系統,涉及三個數據庫,此時我們必須在數據庫和應用系統之間,通過某項黑科技,實現分布式事務的支持。

5. CAP理論

CAP理論說的是:在一個分布式系統中,最多只能滿足C、A、P中的兩個需求。

CAP的含義:

  • C:Consistency 一致性
  • 同一數據的多個副本是否實時相同。
  • A:Availability 可用性
  • 可用性:一定時間內 & 系統返回一個明確的結果 則稱為該系統可用。
  • P:Partition tolerance 分區容錯性
  • 將同一服務分布在多個系統中,從而保證某一個系統宕機,仍然有其他系統提供相同的服務。

CAP理論告訴我們,在分布式系統中,C、A、P三個條件中我們最多只能選擇兩個。那么問題來了,究竟選擇哪兩個條件較為合適呢?

對于一個業務系統來說,可用性和分區容錯性是必須要滿足的兩個條件,并且這兩者是相輔相成的。業務系統之所以使用分布式系統,主要原因有兩個:

  • 提升整體性能
  • 當業務量猛增,單個服務器已經無法滿足我們的業務需求的時候,就需要使用分布式系統,使用多個節點提供相同的功能,從而整體上提升系統的性能,這就是使用分布式系統的第一個原因。
  • 實現分區容錯性
  • 單一節點 或 多個節點處于相同的網絡環境下,那么會存在一定的風險,萬一該機房斷電、該地區發生自然災害,那么業務系統就全面癱瘓了。為了防止這一問題,采用分布式系統,將多個子系統分布在不同的地域、不同的機房中,從而保證系統高可用性。

這說明分區容錯性是分布式系統的根本,如果分區容錯性不能滿足,那使用分布式系統將失去意義。

此外,可用性對業務系統也尤為重要。在大談用戶體驗的今天,如果業務系統時常出現“系統異常”、響應時間過長等情況,這使得用戶對系統的好感度大打折扣,在互聯網行業競爭激烈的今天,相同領域的競爭者不甚枚舉,系統的間歇性不可用會立馬導致用戶流向競爭對手。因此,我們只能通過犧牲一致性來換取系統的可用性分區容錯性。這也就是下面要介紹的BASE理論。

6. BASE理論

CAP理論告訴我們一個悲慘但不得不接受的事實——我們只能在C、A、P中選擇兩個條件。而對于業務系統而言,我們往往選擇犧牲一致性來換取系統的可用性和分區容錯性。不過這里要指出的是,所謂的“犧牲一致性”并不是完全放棄數據一致性,而是犧牲強一致性換取弱一致性。下面來介紹下BASE理論。

  • BA:Basic Available 基本可用
  • “一定時間”可以適當延長
  • 當舉行大促時,響應時間可以適當延長
  • 給部分用戶返回一個降級頁面
  • 給部分用戶直接返回一個降級頁面,從而緩解服務器壓力。但要注意,返回降級頁面仍然是返回明確結果。
  • 整個系統在某些不可抗力的情況下,仍然能夠保證“可用性”,即一定時間內仍然能夠返回一個明確的結果。只不過“基本可用”和“高可用”的區別是:
  • S:Soft State:柔性狀態
  • 同一數據的不同副本的狀態,可以不需要實時一致。
  • E:Eventual Consisstency:最終一致性
  • 同一數據的不同副本的狀態,可以不需要實時一致,但一定要保證經過一定時間后仍然是一致的。

7. 酸堿平衡

ACID能夠保證事務的強一致性,即數據是實時一致的。這在本地事務中是沒有問題的,在分布式事務中,強一致性會極大影響分布式系統的性能,因此分布式系統中遵循BASE理論即可。但分布式系統的不同業務場景對一致性的要求也不同。如交易場景下,就要求強一致性,此時就需要遵循ACID理論,而在注冊成功后發送短信驗證碼等場景下,并不需要實時一致,因此遵循BASE理論即可。因此要根據具體業務場景,在ACID和BASE之間尋求平衡。

8. 分布式事務協議

下面介紹幾種實現分布式事務的協議。

8.1 兩階段提交協議 2PC

分布式系統的一個難點是如何保證架構下多個節點在進行事務性操作的時候保持一致性。為實現這個目的,二階段提交算法的成立基于以下假設:

  • 該分布式系統中,存在一個節點作為協調者(Coordinator),其他節點作為參與者(Cohorts)。且節點之間可以進行網絡通信。
  • 所有節點都采用預寫式日志,且日志被寫入后即被保持在可靠的存儲設備上,即使節點損壞不會導致日志數據的消失。
  • 所有節點不會永久性損壞,即使損壞后仍然可以恢復。

1. 第一階段(投票階段):

  1. 協調者節點向所有參與者節點詢問是否可以執行提交操作(vote),并開始等待各參與者節點的響應。
  2. 參與者節點執行詢問發起為止的所有事務操作,并將Undo信息和Redo信息寫入日志。(注意:若成功這里其實每個參與者已經執行了事務操作)
  3. 各參與者節點響應協調者節點發起的詢問。如果參與者節點的事務操作實際執行成功,則它返回一個"同意"消息;如果參與者節點的事務操作實際執行失敗,則它返回一個"中止"消息。

2. 第二階段(提交執行階段):

當協調者節點從所有參與者節點獲得的相應消息都為"同意"時:

  1. 協調者節點向所有參與者節點發出"正式提交(commit)"的請求。
  2. 參與者節點正式完成操作,并釋放在整個事務期間內占用的資源。
  3. 參與者節點向協調者節點發送"完成"消息。
  4. 協調者節點受到所有參與者節點反饋的"完成"消息后,完成事務。

如果任一參與者節點在第一階段返回的響應消息為"中止",或者 協調者節點在第一階段的詢問超時之前無法獲取所有參與者節點的響應消息時:

  1. 協調者節點向所有參與者節點發出"回滾操作(rollback)"的請求。
  2. 參與者節點利用之前寫入的Undo信息執行回滾,并釋放在整個事務期間內占用的資源。
  3. 參與者節點向協調者節點發送"回滾完成"消息。
  4. 協調者節點受到所有參與者節點反饋的"回滾完成"消息后,取消事務。

不管最后結果如何,第二階段都會結束當前事務。

二階段提交看起來確實能夠提供原子性的操作,但是不幸的事,二階段提交還是有幾個缺點的:

  1. 執行過程中,所有參與節點都是事務阻塞型的。當參與者占有公共資源時,其他第三方節點訪問公共資源不得不處于阻塞狀態。
  2. 參與者發生故障。協調者需要給每個參與者額外指定超時機制,超時后整個事務失敗。(沒有多少容錯機制)
  3. 協調者發生故障。參與者會一直阻塞下去。需要額外的備機進行容錯。(這個可以依賴后面要講的Paxos協議實現HA)
  4. 二階段無法解決的問題:協調者再發出commit消息之后宕機,而唯一接收到這條消息的參與者同時也宕機了。那么即使協調者通過選舉協議產生了新的協調者,這條事務的狀態也是不確定的,沒人知道事務是否被已經提交。

為此,Dale Skeen和Michael Stonebraker在“A Formal Model of Crash Recovery in a Distributed System”中提出了三階段提交協議(3PC)。

8.2 三階段提交協議 3PC

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

  • 引入超時機制。同時在協調者和參與者中都引入超時機制。
  • 在第一階段和第二階段中插入一個準備階段。保證了在最后提交階段之前各參與節點的狀態是一致的。

也就是說,除了引入超時機制之外,3PC把2PC的準備階段再次一分為二,這樣三階段提交就有CanCommit、PreCommit、DoCommit三個階段。

1. CanCommit階段

3PC的CanCommit階段其實和2PC的準備階段很像。協調者向參與者發送commit請求,參與者如果可以提交就返回Yes響應,否則返回No響應。

  1. 事務詢問
  2. 協調者向參與者發送CanCommit請求。詢問是否可以執行事務提交操作。然后開始等待參與者的響應。
  3. 響應反饋
  4. 參與者接到CanCommit請求之后,正常情況下,如果其自身認為可以順利執行事務,則返回Yes響應,并進入預備狀態。否則反饋No

2. PreCommit階段

協調者根據參與者的反應情況來決定是否可以記性事務的PreCommit操作。根據響應情況,有以下兩種可能。

假如協調者從所有的參與者獲得的反饋都是Yes響應,那么就會執行事務的預執行。

  1. 發送預提交請求
  2. 協調者向參與者發送PreCommit請求,并進入Prepared階段。
  3. 事務預提交
  4. 參與者接收到PreCommit請求后,會執行事務操作,并將undo和redo信息記錄到事務日志中。
  5. 響應反饋
  6. 如果參與者成功的執行了事務操作,則返回ACK響應,同時開始等待最終指令。

假如有任何一個參與者向協調者發送了No響應,或者等待超時之后,協調者都沒有接到參與者的響應,那么就執行事務的中斷。

  1. 發送中斷請求
  2. 協調者向所有參與者發送abort請求。
  3. 中斷事務
  4. 參與者收到來自協調者的abort請求之后(或超時之后,仍未收到協調者的請求),執行事務的中斷。

3. doCommit階段

該階段進行真正的事務提交,也可以分為以下兩種情況。

該階段進行真正的事務提交,也可以分為以下兩種情況。

3.1 執行提交

  1. 發送提交請求
  2. 協調接收到參與者發送的ACK響應,那么他將從預提交狀態進入到提交狀態。并向所有參與者發送doCommit請求。
  3. 事務提交
  4. 參與者接收到doCommit請求之后,執行正式的事務提交。并在完成事務提交之后釋放所有事務資源。
  5. 響應反饋
  6. 事務提交完之后,向協調者發送Ack響應。
  7. 完成事務
  8. 協調者接收到所有參與者的ack響應之后,完成事務。

3.2 中斷事務

協調者沒有接收到參與者發送的ACK響應(可能是接受者發送的不是ACK響應,也可能響應超時),那么就會執行中斷事務。

  1. 發送中斷請求
  2. 協調者向所有參與者發送abort請求
  3. 事務回滾
  4. 參與者接收到abort請求之后,利用其在階段二記錄的undo信息來執行事務的回滾操作,并在完成回滾之后釋放所有的事務資源。
  5. 反饋結果
  6. 參與者完成事務回滾之后,向協調者發送ACK消息
  7. 中斷事務
  8. 協調者接收到參與者反饋的ACK消息之后,執行事務的中斷。

最后

另外,如果覺得本文對您有幫助的話,記得關注Wooola、轉發哦,我會為大家持續提供原創干貨。

原文鏈接:https://mp.weixin.qq.com/s/VbFOscil4s4XEbhznisvhQ

分享到:
標簽:微服 架構
用戶無頭像

網友整理

注冊時間:

網站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網站吧!
最新入駐小程序

數獨大挑戰2018-06-03

數獨一種數學游戲,玩家需要根據9

答題星2018-06-03

您可以通過答題星輕松地創建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學四六

運動步數有氧達人2018-06-03

記錄運動步數,積累氧氣值。還可偷

每日養生app2018-06-03

每日養生,天天健康

體育訓練成績評定2018-06-03

通用課目體育訓練成績評定