文章目錄
- 分布式事務
- 2PC(二階段提交協議)
- 執行流程
- 優缺點
- 3PC(三階段提交協議)
- 執行流程
- 優缺點
- 本地消息表(異步確保)
分布式事務
分布式事務就是指事務的參與者、支持事務的服務器、資源服務器以及事務管理器分別位于分布式系統的不同節點之上。
簡言之,就是一次大的操作由不同的小操作組成,這些小的操作分布在不同的服務器上,且屬于不同的應用,分布式事務需要保證這些小操作要么全部成功,要么全部失敗。 本質上來說,分布式事務就是為了保證不同數據庫的數據一致性。
2PC(二階段提交協議)
在分布式系統中,每一個機器節點雖然都能夠明確地知道自己在進行事務操作過程中的結果是成功或失敗,但是卻無法直接獲取到其他分布式節點的操作結果(即無法同步結果,一致性無法保證)。
為了保證事務處理的 ACID
特性,就需要引入一個稱為協調者的組件來統一調度所有分布式節點的執行邏輯,這些被調度的分布式節點則被稱為參與者。協調者負責調度參與者的行為,基于這個思想,衍生出了二階段提交和三階段提交兩種協議。
2PC(Two-Phase Commit): 即二階段提交,是為了使基于分布式系統架構下的所有節點在進行事務處理過程中能夠保持原子性和一致性而設計的一種算法。
執行流程
第一階段的主要內容就是進行投票,來表明是否有繼續執行事務的必要。
階段一:提交事務請求(投票階段)
- 事務詢問: 協調者向所有參與者發出事務詢問,詢問是否可以執行事務操作,并等待各參與者的響應。
- 執行事務: 各個參與者節點執行事務操作,并將
undo
和redo
信息記入事務日志中。 - 各參與者向協調者反饋事務詢問的響應: 如果參與者成功執行事務,則反饋
YES
響應;否則反饋NO
響應。 - 開啟第二階段: 協調者接收到所有參與者的
YES
響應后進入第二階段。
在第二階段中,會根據第一階段參與者的反饋來決定是否能夠提交事務,要么全都成功,要么全都失敗。
階段二:執行事務提交(執行階段)
- 執行事務提交
- 發送提交請求: 協調者向所有參與者發起提交請求。
- 事務提交: 參與者在收到提交請求后,會正式執行事務提交操作。
- 反饋事務提交結果: 參與者在完成事務提交之后向協調者發送
ACK
消息。 - 完成事務: 協調者接收到所有參與者的
ACK
后完成事務。
- 中斷事務(第一階段協調者未收到所有參與者的 YES 響應)
- 發送回滾請求: 協調者向所有參與者發起回滾請求。
- 事務回滾: 參與者在收到回滾請求后,利用階段一記錄的
undo
信息來執行事務回滾操作。 - 反饋事務回滾結果: 參與者在完成事務回滾之后向協調者發送
ACK
消息。 - 中斷事務: 協調者接收到所有參與者的
ACK
后完成事務中斷。
優缺點
- 優點
- 原理簡單
- 實現方便
- 缺點
- 同步阻塞: 在執行過程中,所有參與該事務操作的邏輯都會處于阻塞狀態,也就是說各個參與者在等待其他參與者響應的過程中將無法執行其他操作。
- 單點問題: 在上述過程中,協調者起到了核心的調度作用。一旦協調者出現了問題,那么整個提交流程將無法運轉,甚至如果在二階段的提交流程中出現了問題,將導致其他參與者都處于鎖定事務資源的狀態中,無法完成事務。
- 數據不一致: 倘若在第二階段的提交過程中,協調者向所有參與者發送提交請求,由于網絡原因導致只有部分參與者收到了提交請求,此時就導致了只有接收到請求的參與者進行了事務提交,而產生數據不一致的問題。
- 過于保守: 二階段提交協議沒有設計容錯機制,任意一個節點的失敗都會導致整個事務的失敗。
3PC(三階段提交協議)
3PC(Three-Phase Commit): 即三階段提交,為了解決二階段的缺陷,其將二階段提交協議的提交事務請求過程一分為二,形成了由 CanCommit
、PreCommit
、DoCommint
三個階段組成的事務處理協議:
執行流程
階段一:CanCommit
- 事務詢問
- 各參與者向協調者反饋事務詢問的響應
階段二:PreCommit
-
執行事務預提交
- 發送預提交請求
- 事務預提交
- 各參與者向協調者反饋事務執行的結果
-
中斷事務
- 發送中斷請求
- 中斷事務
階段三:DoCommit
- 執行提交
- 發送提交請求
- 事務提交
- 反饋事務提交結果
- 完成事務
- 中斷事務
- 發送中斷請求
- 事務回滾
- 反饋事務回滾結果
- 中斷事務
需要注意的是,在階段三中可能會出現以下兩種問題:
- 協調者出現問題(單點問題)
- 協調者和參與者之間的網絡出現故障(網絡擁塞)
無論出現上述那種問題,最終都會導致參與者無法及時的接收到來自協調者的 DoCommit
或是 Abort
請求,針對這種異常情況,參與者都會在等待超時后繼續進行事務提交。
優缺點
- 優點: 相較于二階段提交協議,降低了參與者的阻塞范圍,并且能夠在出現單點故障后繼續達成一致。
- 缺點: 三階段提交協議在去除阻塞的同時也引入了新的問題,那就是參與者在收到預提交的消息時,如果出現了網絡分區的情況,協調者與參與者無法進行正常的網絡通信,但是參與者依舊會進行事務的提交,從而導致數據的不一致。
本地消息表(異步確保)
本地消息表與業務數據表處于同一個數據庫中,這樣就能利用本地事務來保證在對這兩個表的操作滿足事務特性,并且使用了消息隊列來保證最終一致性。
- 在分布式事務操作的一方完成寫業務數據的操作之后向本地消息表發送一個消息,本地事務能保證這個消息一定會被寫入本地消息表中。
- 之后將本地消息表中的消息轉發到消息隊列中,如果轉發成功則將消息從本地消息表中刪除,否則繼續重新轉發。
- 在分布式事務操作的另一方從消息隊列中讀取一個消息,并執行消息中的操作。
這里的消息隊列不是單純的數據結構,而應該看作由標志和操作兩部分共同組成的中間件,用以標識某一操作是否成功,只有當左側的分布式節點確實完成了某項操作,右側的其他節點才有同步這項操作的必要。