分布式事務(wù)

分布式事務(wù)是什么?

分布式事務(wù)是指事務(wù)的參與者、支持事務(wù)的服務(wù)器、資源服務(wù)器及事務(wù)的管理器分別位于分布式系統(tǒng)的不同節(jié)點(diǎn)上。對(duì)于傳統(tǒng)的單機(jī)上的事務(wù),所有的事情都在這一臺(tái)機(jī)器上完成,而在分布式事務(wù)中,會(huì)有多個(gè)節(jié)點(diǎn)參與。

來(lái)看一個(gè)分布式事務(wù)的規(guī)范-XA,XA定義的三個(gè)組件:

  • 應(yīng)用程序(AP),它定義了事務(wù)的邊界,并且定義了構(gòu)成該事務(wù)的應(yīng)用程序的特定操作。
  • 資源管理器(RM),可以理解為一個(gè)DBMS系統(tǒng),或者消息服務(wù)器管理系統(tǒng)。應(yīng)用程序通過(guò)RM對(duì)資源進(jìn)行控制,資源必須實(shí)現(xiàn)XA定義的接口。?RM提供了存儲(chǔ)共享資源的支持。
  • 事務(wù)管理器(TM),負(fù)責(zé)協(xié)調(diào)和管理事務(wù),提供給AP編程接口并管理資源管理器。事務(wù)管理器監(jiān)控事務(wù)的進(jìn)程,負(fù)責(zé)處理事務(wù)的完成和失敗。
AP/TM/RM之間的關(guān)系

事務(wù)管理器是額外引入的,之所以要引入事務(wù)管理器,是因?yàn)榉植际较到y(tǒng)中,兩臺(tái)機(jī)器理論上無(wú)法達(dá)到一致的狀態(tài),需要引入一個(gè)單點(diǎn)進(jìn)行協(xié)調(diào)。

兩階段提交

兩階段提交協(xié)議,即2PC。分布式系統(tǒng)中,在提交之前增加了準(zhǔn)備的階段,所以稱為兩階段提交。

第一階段
第二階段

特別地,在準(zhǔn)備階段有一個(gè)資源失敗,那么第二階段處理的就是回滾所有資源。

出問(wèn)題的第一階段
回滾的第二階段

將提交分成兩階段進(jìn)行的目的很明確,就是盡可能晚地提交事務(wù),讓事務(wù)在提交前盡可能地完成所有能完成的工作,這樣,最后的提交階段將是一個(gè)耗時(shí)極短的微小操作,這種操作在一個(gè)分布式系統(tǒng)中失敗的概率是非常小的,也就是所謂的“網(wǎng)絡(luò)通訊危險(xiǎn)期”非常的短暫,這是兩階段提交確保分布式事務(wù)原子性的關(guān)鍵所在。(唯一理論上兩階段提交出現(xiàn)問(wèn)題的情況是當(dāng)協(xié)調(diào)者發(fā)出提交指令后當(dāng)機(jī)并出現(xiàn)磁盤故障等永久性錯(cuò)誤,導(dǎo)致事務(wù)不可追蹤和恢復(fù))

從兩階段提交的工作方式來(lái)看,很顯然,在提交事務(wù)的過(guò)程中需要在多個(gè)節(jié)點(diǎn)之間進(jìn)行協(xié)調(diào),而各節(jié)點(diǎn)對(duì)鎖資源的釋放必須等到事務(wù)最終提交時(shí),這樣,比起一階段提交,兩階段提交在執(zhí)行同樣的事務(wù)時(shí)會(huì)消耗更多時(shí)間。事務(wù)執(zhí)行時(shí)間的延長(zhǎng)意味著鎖資源發(fā)生沖突的概率增加,當(dāng)事務(wù)的并發(fā)量達(dá)到一定數(shù)量的時(shí)候,就會(huì)出現(xiàn)大量事務(wù)積壓甚至出現(xiàn)死鎖,系統(tǒng)性能就會(huì)嚴(yán)重下滑。這就是使用XA事務(wù)。

一階段提交

不像兩階段提交那樣復(fù)雜,一階段提交非常直白,就是從應(yīng)用程序向數(shù)據(jù)庫(kù)發(fā)出提交請(qǐng)求到數(shù)據(jù)庫(kù)完成提交或回滾之后將結(jié)果返回給應(yīng)用程序的過(guò)程。一階段提交不需要“協(xié)調(diào)者”角色,各結(jié)點(diǎn)之間不存在協(xié)調(diào)操作,因此其事務(wù)執(zhí)行時(shí)間比兩階段提交要短,但是提交的“危險(xiǎn)期”是每一個(gè)事務(wù)的實(shí)際提交時(shí)間,相比于兩階段提交,一階段提交出現(xiàn)在“不一致”的概率就變大了。但是我們必須注意到:只有當(dāng)基礎(chǔ)設(shè)施出現(xiàn)問(wèn)題的時(shí)候(如網(wǎng)絡(luò)中斷,當(dāng)機(jī)等),一階段提交才可能會(huì)出現(xiàn)“不一致”的情況,相比它的性能優(yōu)勢(shì),很多團(tuán)隊(duì)都會(huì)選擇這一方案。關(guān)于在spring環(huán)境下如何實(shí)現(xiàn)一階段提交,有一篇非常優(yōu)秀的文章值得參考:http://www.javaworld.com/javaworld/jw-01-2009/jw-01-spring-transactions.html?page=5

像一階段提交這種模式,前提是應(yīng)用程序能獲取所有的數(shù)據(jù)源,然后使用同一個(gè)事務(wù)管理器(這里指是的spring的事務(wù)管理器)管理事務(wù)。這種模式最典型的應(yīng)用場(chǎng)景非數(shù)據(jù)庫(kù)sharding莫屬。但是對(duì)于那些基于web service/rpc/jms等構(gòu)建的高度自治(autonomy)的分布式系統(tǒng)接口,一階段提交模式是無(wú)能為力的,此類場(chǎng)景下,還有最后一種方法可以幫助我們實(shí)現(xiàn)“最終一致性”,那就是事務(wù)補(bǔ)償機(jī)制。

一般而言,需要交互的子系統(tǒng)數(shù)量較少,并且整個(gè)系統(tǒng)在未來(lái)不會(huì)或很少引入新的子系統(tǒng)且負(fù)載長(zhǎng)期保持穩(wěn)定,即無(wú)伸縮要求的話,考慮到開(kāi)發(fā)復(fù)雜度和工作量,可以選擇使用分布式事務(wù)。對(duì)于時(shí)間需求不是很緊,對(duì)性能要求很高的系統(tǒng),應(yīng)考慮使用一階段提交或事務(wù)補(bǔ)償機(jī)制。對(duì)于那些需要進(jìn)行sharding改造的系統(tǒng),基本上不應(yīng)再考慮分布式事務(wù),因?yàn)閟harding打開(kāi)了數(shù)據(jù)庫(kù)水平伸縮的窗口,使用分布式事務(wù)看起來(lái)好像是為新打開(kāi)的窗口又加上了一把枷鎖。

大型網(wǎng)站一致性理的基礎(chǔ)理論-CAP/BASE

我們來(lái)了解一下分布式系統(tǒng)的基礎(chǔ)理論-CAP。

CAP理論:

一致性(C):所有的節(jié)點(diǎn)在同一時(shí)間讀到同樣的數(shù)據(jù)。當(dāng)數(shù)據(jù)寫入成功后,所有的節(jié)點(diǎn)會(huì)同事看到這個(gè)新的數(shù)據(jù)。

可用性(A):保證無(wú)論是成功還是失敗,每個(gè)請(qǐng)求都能夠收到一個(gè)反饋。這就是數(shù)據(jù)的可用性,重點(diǎn)是系統(tǒng)一定要有響應(yīng)。

分區(qū)容忍性(P):即便系統(tǒng)中有部分問(wèn)題或者消息的丟失,但是系統(tǒng)仍能夠繼續(xù)運(yùn)行。

但是,分布式系統(tǒng)不能同時(shí)滿足上面三項(xiàng),一般來(lái)說(shuō),很多分布式系統(tǒng)在設(shè)計(jì)時(shí)的選擇,是放棄一定的一致性,選擇AP。

再來(lái)看看BASE:

基本可用:允許分區(qū)失敗
軟狀態(tài):接受一段時(shí)間的狀態(tài)不同步
最終一致:保證最終的數(shù)據(jù)的狀態(tài)是一致的

所以當(dāng)我們選擇了AP,那么對(duì)于C,采用的策略就是保證最終是一致的。

強(qiáng)一致:所有的節(jié)點(diǎn)在同一時(shí)間讀到同樣的數(shù)據(jù)。

最終一致:犧牲一部分的一致性,可以接受數(shù)據(jù)存在不一致的問(wèn)題,但是通過(guò)重試或其他手段,保證數(shù)據(jù)最終會(huì)達(dá)到一致?tīng)顟B(tài)

Paxos協(xié)議

Paxos協(xié)議,是一個(gè)比兩階段提交要輕量的保證一致性的協(xié)議。

分布式系統(tǒng)中,要面臨和單機(jī)處理完全不一樣的問(wèn)題,例如網(wǎng)絡(luò)問(wèn)題、進(jìn)程or機(jī)器掛掉、進(jìn)程超時(shí)等。這就會(huì)造成消息重復(fù),一段時(shí)間內(nèi)不可達(dá)等現(xiàn)象。Paxos協(xié)議是幫助我們解決分布式系統(tǒng)中一致性大問(wèn)題的一個(gè)方案。

使用Paxos協(xié)議有一個(gè)前提,那就是不存在拜占庭將軍問(wèn)題。簡(jiǎn)單來(lái)說(shuō),就是要有一個(gè)可信的通信環(huán)境,所有信息都是準(zhǔn)確的沒(méi)有被篡改。

Paxos協(xié)議的決議過(guò)程比較復(fù)雜,這里不贅述,有興趣可以自行了解。總結(jié)Paxos的核心原則就是少數(shù)服從多數(shù)。

但是Paxos協(xié)議存在一個(gè)問(wèn)題,如果系統(tǒng)中同事有人提出議案,可能會(huì)出現(xiàn)碰撞導(dǎo)致失敗。然后大家都是重試,重試仍然可能導(dǎo)致失敗。這就會(huì)導(dǎo)致活鎖。

解決的辦法是在整個(gè)集群中設(shè)一個(gè)Leader,所有的議案都由他來(lái)提,這樣就可以避免沖突。而引發(fā)的新問(wèn)題就是如果Leader出問(wèn)題了該如何處理,那就需要再選一個(gè)Leader出來(lái)。

總結(jié)

從工程上來(lái)說(shuō),如果能夠避免分布式事務(wù)的引入,那還是避免為好;如果一定要引入分布式事務(wù),可以考慮最終一致性的方法;從實(shí)現(xiàn)上來(lái)說(shuō),就是通過(guò)補(bǔ)償?shù)臋C(jī)制不斷重試,讓之前因?yàn)楫惓6鴽](méi)有進(jìn)行到底的操作重試或繼續(xù)進(jìn)行,而不是回滾。

參考文獻(xiàn)

大型網(wǎng)站系統(tǒng)與JAVA中間件實(shí)踐
關(guān)于分布式事務(wù)、兩階段提交、一階段提交和事務(wù)補(bǔ)償機(jī)制的研究

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。