來源:北大青鳥總部 2023年05月08日 10:12
隨著微服務(wù)架構(gòu)在各個企業(yè)的滲透,大家都在紛紛的將技術(shù)架構(gòu)轉(zhuǎn)型,從單體式應(yīng)用變成微服務(wù)架構(gòu)式,從單機部署變分布式部署,我們的應(yīng)用也變成了分布式應(yīng)用。在分布式應(yīng)用中,一切就變得復(fù)雜了,如何保障數(shù)據(jù)的一致性變?yōu)樽钪匾膯栴}。在金九銀十的跳槽季中,分布式事務(wù)也成為面試中的必考題,因此今天給大家惡補一波分布式事務(wù)知識,祝大家可以找到一個滿意的工作。
在單體式應(yīng)用中,因為所有的事務(wù)(即某個動作的全流程,比如購物包含付款、下訂單、減庫存三個操作)都在一個環(huán)境里完成,自然可以保障操作的原子性(事務(wù)要么全部成功,要么全部失?。?、一致性(事務(wù)執(zhí)行前后,數(shù)據(jù)從一個狀態(tài)到另一個狀態(tài)必須是一致的)、隔離性(多個并發(fā)事務(wù)相互隔離,互不干擾)、持久性(事務(wù)完成后,對于數(shù)據(jù)庫的更改是永久保存的,不能回滾)。而在微服務(wù)架構(gòu)的分布式應(yīng)用中,事務(wù)變成了分布式事務(wù)(即事務(wù)的參與者、支持事務(wù)的服務(wù)器、資源服務(wù)器、事務(wù)服務(wù)器分別位于不同的分布式系統(tǒng)的不同節(jié)點上),一個操作拆分成了多個服務(wù)完成,一個服務(wù)又在多臺機器上完成。
那么在分布式事務(wù)中,如何保障事務(wù)的一致性呢?解決辦法是基于XA協(xié)議進行擴展的2PC兩階段提交、3PC三階段提交、TCC試驗確認取消方案。那么XA協(xié)議是什么呢?它是一個基于數(shù)據(jù)庫的分布式事務(wù)協(xié)議,包含事務(wù)管理器、本地資源管理器,事務(wù)管理器作為全局的調(diào)度者,對本地資源管理器同一提交或回滾。
我們先來看看2PC(2phasecommit)兩階段提交,它包含兩個階段的提交,第一階段是準備階段,事務(wù)管理器(即協(xié)調(diào)者)詢問資源管理器(即參與者)“老鐵,準備好了沒有?。靠梢赃M行相關(guān)操作了嗎?”,資源管理器根據(jù)自己的情況回答,如果準備好了就會反饋”老板,我這里都準備好了,可以安排對應(yīng)的工作了“。第二階段是執(zhí)行階段,事務(wù)管理器給資源管理器提交一個用戶請求,比如創(chuàng)建訂單,資源管理器就會進行訂單的創(chuàng)建,在創(chuàng)建完成之后,把執(zhí)行結(jié)果返回給事務(wù)管理器。如果事務(wù)管理器收到某一個資源管理器的失敗消息,則直接給所有的資源管理器發(fā)送回滾小心,釋放事務(wù)處理過程中被占用的資源。
在這里,你可能覺得2PC已經(jīng)很完美了,因為每個事務(wù)操作它都先詢問再操作,有異常就回滾,在分布式系統(tǒng)中完完全全的保障了數(shù)據(jù)的一致性。其實不然,它也存在著很多問題,比如如果在第二階段,事務(wù)管理器向資源管理器發(fā)送提交命令后,出現(xiàn)網(wǎng)絡(luò)異常請求,只有部分資源管理器收到消息并執(zhí)行了命令,其它沒有收到提交命令的資源協(xié)調(diào)器就沒有辦法執(zhí)行事務(wù),從而導(dǎo)致了整個分布式系統(tǒng)的數(shù)據(jù)不一致。比如如果事務(wù)管理器出現(xiàn)了問題,資源管理器都還處在等待命令的情況,就沒有辦法完成事務(wù)的操作。
道高一尺,魔高一丈,我們有了3PC(3PhaseCommit)三階段提交,可以把它認為是2PC的升級版。所謂3PC它包含三個階段cancommit、precommit、docommit。相比兩階段提交,它多了一個precommit準備階段,確保在最后提交階段之前,各個參與者資源管理器的狀態(tài)都一致。并且還增加了超時機制,如果協(xié)調(diào)者事務(wù)管理器出現(xiàn)了問題,參與者資源管理器不會一直等待,而是會執(zhí)行命令。
在3PC中,第一階段cancommit,協(xié)調(diào)者會給所有的參與者發(fā)送命令,詢問他們是否可以干活?各個參與者根據(jù)自己的情況進行應(yīng)答,在第一階段確認了所有參與者都可以干活后。第二階段precommit,協(xié)調(diào)者給所有的參與者發(fā)送precommit命令,詢問是否可以先做些準備工作,參與者收到命令后,會根據(jù)自己的情況判斷是否執(zhí)行操作,如果可以則會返回Yes,在協(xié)調(diào)者收到所有參與者的Yes命令后。第三階段docommit,所有的參與者執(zhí)行事務(wù)操作,該加庫存的加庫存、下訂單的下訂單,完成任務(wù)后返回協(xié)調(diào)者“任務(wù)執(zhí)行完畢”。
TCC(try-confirm-cancel)是補償業(yè)務(wù),可以把它理解為在業(yè)務(wù)層面對事務(wù)一致性的保障。2PC、3PC更多是在數(shù)據(jù)庫層面去保障各個節(jié)點的數(shù)據(jù)一致性。在TCC中,針對每一個操作都需要確認和補償,當用戶請求過來時,通過分布式事務(wù)協(xié)調(diào)器進行事務(wù)的啟動,在try階段時是通過try操作去扣除服務(wù)的預(yù)留資源;然后通過分布式事務(wù)協(xié)調(diào)器去提交事務(wù),在confirm階段是確認執(zhí)行業(yè)務(wù)操作后,在預(yù)留的資源基礎(chǔ)上進行購買請求;在cancel階段是處理某個服務(wù)的資源尚未預(yù)留成功時,取消所有資源的預(yù)留請求。
TCC方案倒是很好的保障了數(shù)據(jù)一致性,但是它也存在一些問題,比如對業(yè)務(wù)有入侵,我們看到每個服務(wù)的操作都包含try、confirm、cancel。