事务超时时间无效_阿里分布式事务组件 fescar/seata 对 XA 2PC 的改进及其设计思想...
1. 二階段提交協議的由來
X/Open 組織提出了分布式事務處理的規范 DTP 模型(Distributed Transaction Processing),該模型中主要定義了三個基本組件,分別是
應用程序(Application?Program?,簡稱AP):用于定義事務邊界(即定義事務的開始和結束),并且在事務邊界內對資源進行操作。
資源管理器(Resource?Manager,簡稱RM):如數據庫、文件系統等,并提供訪問資源的方式。
事務管理器(Transaction?Manager?,簡稱TM):負責分配事務唯一標識,監控事務的執行進度,并負責事務的提交、回滾等。
一般,我們稱TM為事務的協調者,而稱RM為事務的參與者。TM?與?RM?之間的通信接口,則由?XA?規范來約定。
在?DTP?模型的基礎上,才引出了二階段提交協議來處理分布式事務。
2. 二階段提交基本算法
2.1 前提
二階段提交協議能夠正確運轉,需要具備以下前提條件:
存在一個協調者,與多個參與者,且協調者與參與者之間可以進行網絡通信
參與者節點采用預寫式日志,日志保存在可靠的存儲設備上,即使參與者損壞,不會導致日志數據的消失
參與者節點不會永久性損壞,即使后仍然可以恢復
實際上,條件2和3所要求的,現今絕大多數關系型數據庫都能滿足。
2.2 基本算法
2.2.1 第一階段
協調者節點向所有參與者節點詢問是否可以執行提交操作,并開始等待各參與者節點的響應。
參與者節點執行詢問發起為止的所有事務操作,并將Undo信息和Redo信息寫入日志。
各參與者節點響應協調者節點發起的詢問。如果參與者節點的事務操作實際執行成功,則它返回一個"同意"消息;如果參與者節點的事務操作實際執行失敗,則它返回一個"中止"消息。
2.2.2 第二階段
當協調者節點從所有參與者節點獲得的相應消息都為"同意"時:
協調者節點向所有參與者節點發出"正式提交"的請求。
參與者節點正式完成操作,并釋放在整個事務期間內占用的資源。
參與者節點向協調者節點發送"完成"消息。
協調者節點收到所有參與者節點反饋的"完成"消息后,完成事務。
如下圖所示:
如果任一參與者節點在第一階段返回的響應消息為"終止",或者?協調者節點在第一階段的詢問超時之前無法獲取所有參與者節點的響應消息時:
協調者節點向所有參與者節點發出"回滾操作"的請求。
參與者節點利用之前寫入的Undo信息執行回滾,并釋放在整個事務期間內占用的資源。
參與者節點向協調者節點發送"回滾完成"消息。
協調者節點收到所有參與者節點反饋的"回滾完成"消息后,取消事務。
如下圖所示:
3. 二階段提交缺陷分析
二階段提交協議除了協議本身具有的局限性之外,如果我們把以下情況也考慮在內:
協調者宕機
參與者宕機
網絡閃斷(腦裂)
那么二階段提交協議實際上是存在很多問題的
3.1協議本身的缺陷
協議本身的缺陷是指,在協議正常運行的情況下,無論全局事務最終是被提交還是被回滾,依然存在的問題,而暫不考慮參與者或者協調者宕機,或者腦裂的情況。
3.1.1 性能問題
當網絡閃斷發生在第一階段時,可能會有部分參與者進入阻塞狀態,全局事務無法結束。
當發生在第二階段時,可能發生部分參與者執行了?commit?而部分參與者未執行?commit,從而導致全局數據不一致的問題。
參與者的本地事務開啟后,直到它接收到協調者的?commit?或?rollback? 命令后,它才會提交或回滾本地事務,并且釋放由于事務的存在而鎖定的資源。不幸的是,一個參與者收到協調者的?commit?或者?rollback? 的前提是:協調者收到了所有參與者在一階段的回復。
如果說,協調者一階段詢問多個參與者采用的是順序詢問的方式,那么一個參與者最快也要等到協調者詢問完所有其它的參與者后才會被通知提交或回滾,在協調者未詢問完成之前,這個參與者將保持占用相關的事務資源。
即使,協調者一階段詢問多個參與者采用的是并發詢問的方式,那么一個參與者等待收到協調者的提交或者回滾通知的時間,將取決于在一階段過程中,響應協調者最慢的那個參與者的響應時間。
無論是哪一種情況,參與者都將在整個一階段持續的時間里,占用住相關的資源,參與者事務的處理時間增加。若此時在參與者身上有其它事務正在進行,那么其它事務有可能因為與這個延遲的事務有沖突,而被阻塞,這些被阻塞的事務,進而會引起其它事務的阻塞。
總而言之,整體事務的平均耗時增加了,整體事務的吞吐量也降低了。這會使得整個應用系統的延遲變高,吞吐量降低,可擴展性降低(當參與者變多的時候,延遲可能更嚴重)。
總的來說,二階段提交協議,不是一個高效的協議,會帶來性能上的損失。
3.1.2 全局事務隔離性的問題
全局事務的隔離性與單機事務的隔離性是不同的。
當我們在單機事務中提到不允許臟讀時,那么意味著在事務未提交之前,它對數據造成的影響不應該對其它事務可見。
當我們在全局事務中提到不允許臟讀時,意味著,在全局事務未提交之前,它對數據造成的影響不應該對其它事務可見。
在二階段提交協議中,當在第二階段所有的參與者都成功執行 ?commit?或者?rollback?之后,全局事務才算結束。但第二階段存在這樣的中間狀態:即部分參與者已執行?commit?或者? rollback,而其它參與者還未執行?commit?或者?rollback。此刻,已經執行?commit?或者?rollback? 的參與者,它對它本地數據的影響,對其它全局事務是可見的,即存在臟讀的風險。對于這種情況,二階段協議并沒有任何機制來保證全局事務的隔離性,無法做到“讀已提交”這樣的隔離級別。
3.2 協調者宕機
如果在第一階段,協調者發生了宕機,那么因為所有參與者無法再接收到協調者第二階段的 commit 或者 rollback 命令,所以他們會阻塞下去,本地事務無法結束,
如果協調者在第二階段發生了宕機,那么可能存在部分參與者接收到了?commit/rollback?命令,而部分沒有,因此這部分沒有接收到命令的參與者也會一直阻塞下去。
協調者宕機屬于單點問題,可以通過另選一個協調者的方式來解決,但這只能保證后續的全局事務正常運行。而因為之前協調者宕機而造成的參與者阻塞則無法避免。如果這個新選擇的協調者也宕機了,那么一樣會帶來阻塞的問題。
3.3 參與者宕機
如果在第一階段,某個參與者發生了宕機,那么會導致協調者一直等待這個參與者的響應,進而導致其它參與者也進入阻塞狀態,全局事務無法結束。
如果在第二階段,協調者發起?commit?操作時,某個參與者發生了宕機,那么全局事務已經執行了?commit?的參與者的數據已經落盤,而宕機的參與者可能還沒落盤,當參與者恢復過來的時候,就會產生全局數據不一致的問題。
3.4 網絡問題-腦裂
當網絡閃斷發生在第一階段時,可能會有部分參與者進入阻塞狀態,全局事務無法結束。
當發生在第二階段時,可能發生部分參與者執行了?commit?而部分參與者未執行?commit,從而導致全局數據不一致的問題。
4. 三階段提交
在二階段提交中,當協調者宕機的時候,無論是在第一階段還是在第二階段發生宕機,參與者都會因為等待協調者的命令而進入阻塞狀態,從而導致全局事務無法繼續進行。因此,如果在參與者中引入超時機制,即,當指定時間過去之后,參與者自行提交或者回滾。但是,參與者應該進行提交還是回滾呢?悲觀的做法是,統一都回滾。但事情往往沒那么簡單。
當第一階段,協調者宕機時,那么所有被阻塞的參與者選擇超時后回滾事務是最明智的做法,因為還未進入第二階段,所以參與者都不會接收到提交或者回滾的請求,當前這個事務是無法繼續進行提交的,因為參與者不知道其它參與者的執行情況,所以統一回滾,結束分布式事務。
在二階段提交協議中的第二階段,當協調者宕機后,由于參與者無法知道協調者在宕機前給其他參與者發了什么命令,進入了第二階段,全局事務要么提交要么回滾,參與者如果引入超時機制,那么它應該在超時之后提交還是回滾呢,似乎怎么樣都不是正確的做法。執行回滾,太保守,執行提交,太激進。
如果在二階段提交協議中,在第一階段和第二階段中間再引入一個階段,如果全局事務度過了中間這個階段,那么在第三階段,參與者就可以認為此刻進行提交的成功率會更大。但這難道不是治標不治本嗎,當進入第三階段,全局事務需要進行回滾時候,如果協調者宕機,那么參與者超時之后自行進行提交事務,就會造成全局事務的數據不一致。
再考慮參與者宕機的情況下,協調者應該在超時之后,對全局事務進行回滾。
總結起來,三階段提交主要在二階段提交的基礎上,為了解決參與者和協調者宕機的問題,而引入了超時機制,并因為超時機制,附帶引入中間這一層。
并且,三階段提交并沒有解決二階段提交的存在的腦裂的問題。
總而言之,二階段和三階段提交都無法完美地解決分布式事務的問題。關于三階段提交更詳細的算法和步驟,可以參考我的另外一篇文章《分布式事務概覽》
5. fescar/seata 二階段提交
總結
以上是生活随笔為你收集整理的事务超时时间无效_阿里分布式事务组件 fescar/seata 对 XA 2PC 的改进及其设计思想...的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: rp软件app流程图_Axure RP
- 下一篇: 极星首款手机 Polestar Phon