三階段提交協議如何避免協調者狀態未知的情況?
二階段提交協議中,如果協調者出問題,整個事物的狀態就會block,三階段如何避免這種情況呢 ?
個人覺得從故障恢復的角度來看更有意思。如果只有coordinator掛了,那麼即時選出新的coordinator,然後詢問participants掛掉時各自最近的狀態,這樣應該不算真正阻塞(當然也可以叫阻塞...),另外如果只有participant掛了,這裡討論應該也沒太大意義。但是一旦一個coordinator和至少一個participant掛了,那麼:1. 2PC不能保證掛掉的節點是已經commit還是abort:比如剩下節點最近的日誌都是第一階段的accept,這時新的coordinator無法判斷掛掉的節點是commit還是abort,因此整個系統全局事務狀態無法確定,只有等著,此時無論新的coordinator做commit或者abort決定,都可能造成與掛掉節點恢復後的不一致。
2. 3PC把commit階段分成兩階段,prepare-commit和commit,然後加上超時機制,這樣就防止了2PC在commit階段的上述情況,因為通過prepare-commit階段,3PC新的coordinator在commit階段即使有participant掛掉也可以確定整個系統的狀態:對比2PC,比如剩下的節點最近的日誌都是第一階段的accept,那麼不可能有人進入commit,因為所有節點必須經過prepare-commit,此時掛掉節點可能是第一階段cancel或者accept或者prepare-commit,可以安全選擇abort;如果至少有一個節點收到prepare-commit了,那麼說明participant不可能在第一階段的應答中就cancel了,即要麼是accept,prepare-commit或者commit,而這三種情況下,整個系統都是可以決定提交的;如果有至少一個返回commit了,那麼掛掉的節點只可能是prepare-commit和commit狀態,這樣整個系統狀態也是可以提交的。總之,在有coordinator和participant掛掉的情況下,無論剩餘存活節點是超時決定abort還是commit,都不會造成整個系統狀態的不一致,因此整個事務可以得到處理,其佔有的鎖等資源可以釋放,不會阻塞其他事務的進行。
假設協調者為C,參與者為A,B, 如下場景仍然有問題:
1.A: pre commit狀態 B: accept狀態此時C,A掛掉。
2.C起來之後,發現B是accepted,因此決定abort
B: 變成abort狀態,但是在B返回C成功之前,B就掛掉了。 C節點也在這個時候掛掉了。3.C,A節點又恢復回來:
此時C發現A是prepare commit因此決定commit。
這樣A,B狀態就已經不一致了。推薦閱讀:
※常用的分散式事務解決方案介紹有多少種?
※如何理解阿里大神程立的分散式事務文檔?
※阿里雲的分散式事務中間件是什麼實現的?