<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          我還不懂什么是分布式事務(wù)

          共 5344字,需瀏覽 11分鐘

           ·

          2021-03-31 12:14

          老大:來(lái),你搞一搞分布式事務(wù)吧

          我:......,啥是事務(wù)?

          我:先從理論學(xué)起吧

          我不懂什么是事務(wù)

          如果事務(wù)都不懂,就更不用說(shuō)分布式事務(wù)了,于是我馬上開(kāi)始學(xué)習(xí)了。

          事務(wù)是應(yīng)用程序中一系列嚴(yán)密的操作,所有操作必須成功完成,否則在每個(gè)操作中所作的所有更改都會(huì)被撤消。

          事務(wù)應(yīng)該具有 4 個(gè)屬性:原子性、一致性、隔離性、持久性。這四個(gè)屬性通常稱(chēng)為 ACID 特性。

          換成比較容易理解的話就是,就是一組操作比如增刪改查四個(gè)操作要么都成功,要么都失敗,不存結(jié)果不一致的狀態(tài)。

          我不懂什么是分布式事務(wù)

          終于弄明白什么是事務(wù)了,又來(lái)了分布式事務(wù)。為什么需要分布式事務(wù)呢?

          事務(wù)更多指的是單機(jī)版、單數(shù)據(jù)庫(kù)的概念。分布式事務(wù) 指事務(wù)的參與者、支持事務(wù)的服務(wù)器、資源服務(wù)器以及事務(wù)管理器分別位于不同的分布式系統(tǒng)的不同節(jié)點(diǎn)之上 。

          換成比較容易理解的話,就是多個(gè)事務(wù)之間再保持事務(wù)的特性,也就是多個(gè)事務(wù)之間保證結(jié)果的一致性。

          XA規(guī)范

          有了分布式事務(wù)的場(chǎng)景,就會(huì)有解決該問(wèn)題的方式規(guī)范,XA規(guī)范就是解決分布式事務(wù)的規(guī)范,具體描述見(jiàn)維基百科解釋?zhuān)?/p>

          XA規(guī)范提供了一種重要思想:

          1、引入全局事務(wù)的控制節(jié)點(diǎn),事務(wù)的協(xié)調(diào)者

          2、多個(gè)本地事務(wù)劃分多階段提交(也就是下面講的2PC,3PC)

          我不懂分布式方案

          有了規(guī)范就會(huì)有落地方案,下面介紹基于XA規(guī)范的幾個(gè)實(shí)現(xiàn)協(xié)議。

          首先介紹兩階段提交( Two-phase Commit )和三階段提交( Three-phase Commit )

          2PC( Two-phase Commit )

          兩階段提交,顧名思義就是要分兩步提交。

          這里第一階段稱(chēng)為準(zhǔn)備或者投票階段。引入一個(gè)負(fù)責(zé)協(xié)調(diào)各個(gè)本地資源管理器的事務(wù)管理器,

          本地資源管理器一般是由數(shù)據(jù)庫(kù)實(shí)現(xiàn),事務(wù)管理器在第一階段的時(shí)候詢(xún)問(wèn)各個(gè)資源管理器是否都就緒,并執(zhí)行完除提交事務(wù)外所有事情,然后把結(jié)果返回給事務(wù)協(xié)調(diào)者。

          如果收到每個(gè)資源的回復(fù)都是 成功,則在第二階段提交事務(wù),如果其中任意一個(gè)資源的回復(fù)是 失敗, 則回滾事務(wù)。

          這里的實(shí)現(xiàn)方式和我們平常開(kāi)黑玩游戲時(shí)差不多,當(dāng)我們組隊(duì)時(shí),隊(duì)長(zhǎng)會(huì)讓大家準(zhǔn)備,讓隊(duì)員上完廁所吃飽飯,如果所有隊(duì)員都準(zhǔn)備好,那就開(kāi)始游戲,如果有任一一個(gè)隊(duì)員沒(méi)有吃飽,沒(méi)有確認(rèn)準(zhǔn)備好,就不會(huì)開(kāi)始游戲。

          但是這種協(xié)議也會(huì)存在一些問(wèn)題,如下:

          同步阻塞,這是2PC最大的問(wèn)題, 嚴(yán)格的2PC執(zhí)行過(guò)程中,所有參與節(jié)點(diǎn)都是事務(wù)阻塞型的。當(dāng)參與者占有公共資源時(shí),其他第三方節(jié)點(diǎn)訪問(wèn)公共資源不得不處于阻塞狀態(tài)

          解決方案:引入引入超時(shí)機(jī)制,如果長(zhǎng)時(shí)間沒(méi)有收到響應(yīng),執(zhí)行特定的動(dòng)作。

          協(xié)調(diào)者單點(diǎn)故障,協(xié)調(diào)者在2PC中是最重要的角色,同時(shí)也意味著如果他出問(wèn)題,整個(gè)過(guò)程就GG了

          解決方案:?jiǎn)吸c(diǎn)故障的常規(guī)方案就引入副本然后當(dāng)主節(jié)點(diǎn)掛掉后,重新選主,就像組隊(duì)游戲中,如果隊(duì)員都準(zhǔn)備好后,隊(duì)長(zhǎng)長(zhǎng)時(shí)間蹲廁所不開(kāi)始游戲,游戲程序一般就會(huì)踢掉隊(duì)長(zhǎng),其他組員切換成隊(duì)長(zhǎng)身份。

          數(shù)據(jù)不一致,雖然解決了上面幾個(gè)問(wèn)題,但是由于分布式系統(tǒng)存在很多網(wǎng)絡(luò)抖動(dòng)和調(diào)用失敗場(chǎng)景還是會(huì)有數(shù)據(jù)不一致的情況,下面分為協(xié)調(diào)者、參與者、網(wǎng)絡(luò)等故障來(lái)詳細(xì)分析一下:

          1、協(xié)調(diào)者發(fā)送準(zhǔn)備命令前掛掉

          這種相當(dāng)于事務(wù)直接沒(méi)有開(kāi)始,沒(méi)有啥太大影響

          2、協(xié)調(diào)者發(fā)送準(zhǔn)備命令后掛掉

          這種情況,如果參與者沒(méi)有超時(shí)機(jī)制,就會(huì)造成資源鎖定

          3、協(xié)調(diào)者發(fā)送提交命令前掛掉

          這種情況和上一種情況類(lèi)似,也會(huì)造成資源鎖定

          4、協(xié)調(diào)者發(fā)送提交命令后掛掉

          這種情況很可能是能夠成功執(zhí)行分布式事務(wù)的,因?yàn)橐呀?jīng)到了提交階段說(shuō)明其他參與者都已經(jīng)準(zhǔn)備好,如果失敗就不斷重試

          5、協(xié)調(diào)者發(fā)送回滾命令前掛掉

          這種情況和2、3是類(lèi)似的,由于參與者收不到執(zhí)行操作的命令,如果沒(méi)有超時(shí)會(huì)一直阻塞并占據(jù)著資源

          6、協(xié)調(diào)者發(fā)送回滾命令后掛掉

          這種情況和4差不多,也是很大概率是能夠成功執(zhí)行回滾事務(wù)的,如果沒(méi)有成功,由于已經(jīng)形成了決議,所以只能不斷重試

          7、協(xié)調(diào)者發(fā)送準(zhǔn)備命令后,部分參與者掛掉

          這種情況協(xié)調(diào)者有超時(shí)機(jī)制,直接判定成失敗,然后通知所有參與者回滾

          8、協(xié)調(diào)者發(fā)送準(zhǔn)備命令后掛掉,且部分參與者掛掉

          這種情況重新選舉協(xié)調(diào)者后,發(fā)現(xiàn)還在第一階段,由于沒(méi)有收到掛掉參與者的響應(yīng),所以判定失敗,通知其他參與者執(zhí)行回滾

          9、協(xié)調(diào)者發(fā)送提交或回滾命令后掛掉,且收到消息的參與者掛掉

          這種情況重新選舉協(xié)調(diào)者后,沒(méi)有收到消息的參與者沒(méi)有執(zhí)行事務(wù),但是協(xié)調(diào)者無(wú)法確定收到消息的參與者執(zhí)行第二階段的提交或回滾到底是否成功,就會(huì)出現(xiàn)事務(wù)不一致的情況

          3PC( Three-phase Commit )

          從上面介紹的相關(guān)內(nèi)容也可以大體知道2PC的缺點(diǎn)和解決方式,于是就有了下面的解決協(xié)議,三階段提交

          從百科可以看到3PC的引入主要就是為了解決上面我們說(shuō)的2PC的缺點(diǎn),咋就能解決呢?

          1、3PC是非阻塞協(xié)議

          好的,就是為了解決了資源占用問(wèn)題,主要也就是引入了參與者超時(shí)機(jī)制

          2、 第一階段與第二階段之間插入了一個(gè)準(zhǔn)備階段

          解決了在兩階段提交中,參與者在投票之后,由于協(xié)調(diào)者發(fā)生崩潰或錯(cuò)誤,而導(dǎo)致參與者處于無(wú)法知曉是否提交或者回滾的“不確定狀態(tài)”,也就是為了保證最后提交階段之前所有參與節(jié)點(diǎn)狀態(tài)一致

          3PC 把2PC第一階段再次拆分為2個(gè)階段,多了一個(gè)階段其實(shí)就是在執(zhí)行事務(wù)之前來(lái)確認(rèn)參與者是否正常,防止個(gè)別參與者不正常的情況下,其他參與者都執(zhí)行了事務(wù)鎖定資源。

          他的大概步驟其實(shí)可以按照參與者4個(gè)狀態(tài)來(lái)劃分

          0、初始狀態(tài),此階段事務(wù)發(fā)起者觸發(fā)全局事務(wù),參與者切換本地狀態(tài)為開(kāi)始狀態(tài),并把自己注冊(cè)到協(xié)調(diào)者中。

          1、可提交或狀態(tài)等待,此階段協(xié)調(diào)者發(fā)送命令到每個(gè)注冊(cè)過(guò)來(lái)的參與者,讓他們更改狀態(tài)為可提交狀態(tài)。

          2、預(yù)提交狀態(tài),此階段協(xié)調(diào)者收到參與者確認(rèn)可以提交并進(jìn)入狀態(tài),然后協(xié)調(diào)者向他們發(fā)送預(yù)提交消息,參與者鎖定資源,并更改狀態(tài)為預(yù)提交狀態(tài)。同時(shí) 協(xié)調(diào)者也進(jìn)入預(yù)提交狀態(tài)。

          3、提交狀態(tài),此階段協(xié)調(diào)者根據(jù)參與者預(yù)提交的結(jié)果執(zhí)行提交或回滾操作,然后釋放資源。

          通過(guò)這種方式可以解決一些2PC狀態(tài)不一致問(wèn)題。JBoss上大佬的總結(jié):

          大概意思是,通過(guò)引入預(yù)提交階段,協(xié)調(diào)者能夠確定參與者提交前的狀態(tài),同時(shí)參與者也能夠推斷其他參與者狀態(tài)

          協(xié)調(diào)者正常的情況下,可以根據(jù)參與者狀態(tài)切換的結(jié)果來(lái)決定是執(zhí)行還是回滾。多出的一個(gè)預(yù)提交階段就是為了統(tǒng)一狀態(tài)。

          參與者如果沒(méi)有收到協(xié)調(diào)者消息,會(huì)默認(rèn)執(zhí)行提交,雖然可能會(huì)導(dǎo)致數(shù)據(jù)不一致。

          協(xié)調(diào)者掛掉重新選舉后,會(huì)根據(jù)參與者和原主節(jié)點(diǎn)狀態(tài)確定是執(zhí)行還是回滾。

          新協(xié)調(diào)者來(lái)的時(shí)候發(fā)現(xiàn)自己是可提交狀態(tài)并且參與者為可提交和回滾狀態(tài),說(shuō)明經(jīng)過(guò)投票回滾的,此時(shí)新協(xié)調(diào)者執(zhí)行回滾命令

          新協(xié)調(diào)者來(lái)的時(shí)候發(fā)現(xiàn)自己是預(yù)提交并且參與者處于預(yù)提交和提交狀態(tài),那么表明已經(jīng)經(jīng)過(guò)了所有參與者的確認(rèn)了,所以此時(shí)執(zhí)行的就是提交命令

          可以看到3PC由于多引入了一個(gè)階段,性能會(huì)比較低,而且其實(shí)也沒(méi)有解決數(shù)據(jù)一致性問(wèn)題,多了一個(gè)階段的效果也不能保證效果一定要比2PC要好,所以一般還是很少用。

          TCC(Try-Confirm-Cancel)

          2PC/3PC 模式基于 支持本地 ACID 事務(wù)關(guān)系型數(shù)據(jù)庫(kù)

          • 一階段 prepare 行為:在本地事務(wù)中,一并提交業(yè)務(wù)數(shù)據(jù)更新和相應(yīng)回滾日志記錄。
          • 二階段 commit 行為:馬上成功結(jié)束,自動(dòng) 異步批量清理回滾日志。
          • 二階段 rollback 行為:通過(guò)回滾日志,自動(dòng) 生成補(bǔ)償操作,完成數(shù)據(jù)回滾。

          相應(yīng)的,TCC 模式從業(yè)務(wù)層面處理,不依賴(lài)于底層數(shù)據(jù)資源的事務(wù)支持:

          • 一階段 prepare 行為:調(diào)用 自定義 的 prepare 邏輯。
          • 二階段 commit 行為:調(diào)用 自定義 的 commit 邏輯。
          • 二階段 rollback 行為:調(diào)用 自定義 的 rollback 邏輯。

          所謂 TCC 模式,是指支持把 自定義 的分支事務(wù)納入到全局事務(wù)的管理中,可以不依賴(lài)本地?cái)?shù)據(jù)庫(kù),當(dāng)然實(shí)現(xiàn)上可以依賴(lài),更多的場(chǎng)景還是兩者結(jié)合。

          TCC更多的是讓業(yè)務(wù)來(lái)實(shí)現(xiàn)兩階段提交的思想,對(duì)業(yè)務(wù)侵入性大

          Try階段定義為執(zhí)行資源的鎖定,這個(gè)階段我認(rèn)為比較難實(shí)現(xiàn),常規(guī)的思路是

          轉(zhuǎn)賬場(chǎng)景時(shí)可能需要把嘗試賬戶(hù)余額是否足夠,然后減去轉(zhuǎn)賬金額并把金額存入到臨時(shí)字段,做到鎖定金額

          緩存場(chǎng)景可能就需要使用分布式鎖,鎖定住要操作的緩存值,或者取出某個(gè)緩存到另一個(gè)緩存

          上傳下載場(chǎng)景可能需要把文件存到服務(wù)器臨時(shí)目錄

          Confirm階段定義為執(zhí)行try階段鎖定的資源,也就是說(shuō)基于try的成功,可以繼續(xù)操作,比如執(zhí)行真正的轉(zhuǎn)賬、緩存操作、上傳下載等。

          Cancel階段定義為釋放Try預(yù)留的資源,也就是說(shuō)由于Try的失敗,需要作出相應(yīng)的補(bǔ)償操作或者恢復(fù)環(huán)境,比如刪除掉轉(zhuǎn)賬時(shí)的臨時(shí)字段、釋放掉鎖、清理臨時(shí)文件等。

          TCC模式實(shí)現(xiàn)難度還是蠻大的,需要考慮很多異常場(chǎng)景,還要考慮資源如何鎖定和釋放,但是由于不會(huì)阻塞資源,應(yīng)用方面也更廣,據(jù)說(shuō)還是有很多公司熱衷于這種補(bǔ)償型的事務(wù)實(shí)現(xiàn)方式

          還有就是這里所說(shuō)的TCC更多是一種思想,實(shí)際實(shí)現(xiàn)可能還是需要根據(jù)具體業(yè)務(wù)來(lái)做相應(yīng)的調(diào)整,方法是死的,人是活的。

          SAGA

          理論基礎(chǔ)(點(diǎn)擊查看原論文):Hector & Kenneth 發(fā)表論文Sagas (1987)

          Saga模式提供的是長(zhǎng)事務(wù)解決方案,在Saga模式中,業(yè)務(wù)流程中每個(gè)參與者都提交本地事務(wù),當(dāng)出現(xiàn)某一個(gè)參與者失敗則補(bǔ)償前面已經(jīng)成功的參與者,一階段正向服務(wù)和二階段補(bǔ)償服務(wù)都由業(yè)務(wù)開(kāi)發(fā)實(shí)現(xiàn)。

          適用場(chǎng)景:

          • 業(yè)務(wù)流程長(zhǎng)、業(yè)務(wù)流程多
          • 參與者包含其它公司或遺留系統(tǒng)服務(wù),無(wú)法提供 TCC 模式要求的三個(gè)接口

          Saga主要思想是依賴(lài)于狀態(tài)機(jī)轉(zhuǎn)換,長(zhǎng)事務(wù)拆分成多個(gè)短事務(wù),依次執(zhí)行短事務(wù)

          如果某個(gè)短事務(wù)失敗,則按照前面執(zhí)行順序的逆序執(zhí)行補(bǔ)償事務(wù)

          這種模式還少使用的,實(shí)現(xiàn)也是比較復(fù)雜,同時(shí)流程很長(zhǎng),當(dāng)遇到類(lèi)似場(chǎng)景時(shí)還是需要仔細(xì)考慮是否有必要去實(shí)現(xiàn)分布式事務(wù)呢?

          本地消息表

          執(zhí)行業(yè)務(wù)的時(shí)候 將業(yè)務(wù)的執(zhí)行和將消息放入消息表中的操作放在同一個(gè)事務(wù)中,這樣就能保證消息放入本地表中業(yè)務(wù)肯定是執(zhí)行成功的。

          然后再去調(diào)用下一個(gè)服務(wù),如果成功了,消息表的消息狀態(tài)可以直接改成已成功。

          如果調(diào)用失敗,會(huì)有 后臺(tái)任務(wù)定時(shí)去讀取本地消息表,篩選出還未成功的消息再調(diào)用對(duì)應(yīng)的服務(wù),服務(wù)更新成功了再變更消息的狀態(tài)。

          一般也會(huì)有重試次數(shù)限制,超出后執(zhí)行回滾或者通知人工介入。

          可見(jiàn)本地消息表也會(huì)出現(xiàn)數(shù)據(jù)不一致的情況,盡量保證最終一致性。

          消息隊(duì)列

          此方案的意思是通過(guò)支持事務(wù)的消息隊(duì)列來(lái)實(shí)現(xiàn)分布式事務(wù)。

          主要流程:

          1. 生產(chǎn)者發(fā)送半事務(wù)消息到MQ
          2. 生產(chǎn)者收到MQ成功接收到之后,去執(zhí)行本地事務(wù),但是事務(wù)還沒(méi)有提交。
          3. 生產(chǎn)者會(huì)根據(jù)事務(wù)的執(zhí)行結(jié)果來(lái)決定發(fā)送提交或者回滾到消息
          4. 生產(chǎn)者需要提供一個(gè)查詢(xún)事務(wù)狀態(tài)接口,如果一段時(shí)間內(nèi)半消息沒(méi)有收到任何操作請(qǐng)求,那么 MQ 會(huì)通過(guò)查詢(xún)接口獲得發(fā)送方事務(wù)執(zhí)行結(jié)果。
          5. 如果是失敗結(jié)果的消息,MQ直接丟棄,也就不會(huì)影響到消費(fèi)者
          6. 如果是成功結(jié)果的消息,消費(fèi)者消費(fèi)半事務(wù)消息,然后再去消費(fèi)普通消息

          該方案與本地消息不同點(diǎn)是去掉了本地消息表,本地事務(wù)和MQ事務(wù)綁定在一起。目前市面上實(shí)現(xiàn)該方案的應(yīng)該只有阿里的 RocketMq

          最大努力通知

          這種方式請(qǐng)進(jìn)行最大努力自行學(xué)習(xí)吧

          我不懂怎么實(shí)現(xiàn)

          學(xué)了這么多方案,自己實(shí)現(xiàn)還是很有難度。

          常見(jiàn)的解決方案的實(shí)現(xiàn)框架有:byteTCC 、華為 ServiceComb 實(shí)現(xiàn)的DTM(華為cloud官網(wǎng)可見(jiàn))、阿里seata(收費(fèi)版為GTS)、騰訊DTF

          目前開(kāi)源最火的還是seata,支持模式多、官網(wǎng)文檔詳細(xì),這里就不一一介紹了

          關(guān)于seata的文章非常多,下篇文章也打算以seata框架實(shí)踐分布式事務(wù)。

          那seata是不是就完美了呢?當(dāng)然不是,以后可能改進(jìn)的幾點(diǎn)

          1、不支持控制臺(tái),沒(méi)有可視化界面,驗(yàn)證全靠打印和連接數(shù)據(jù)庫(kù)

          2、seata-server高可用不支持Raft協(xié)議,事務(wù)信息完全依賴(lài)于DB、redis等

          3、undoLog占用空間過(guò)大尤其是前后置鏡像一個(gè)大JSON字段,數(shù)據(jù)量大時(shí)可能會(huì)入庫(kù)慢,可能需要進(jìn)行壓縮

          4、只能通過(guò)異?;貪L,不支持類(lèi)似Spring的Rollback-Only標(biāo)志位回滾

          5、全局鎖的粒度是不是有點(diǎn)大,分支事務(wù)是否有必要上報(bào)狀態(tài)到TC

          找到一份seata開(kāi)源作者 jimin slievrly 的分享視頻一起學(xué)習(xí)

          如果需要視頻中PPT學(xué)習(xí),公眾號(hào)內(nèi)回復(fù)seata即可

          我懂了

          本文按照完全沒(méi)接觸過(guò)事務(wù)的學(xué)習(xí)流程進(jìn)行書(shū)寫(xiě),腦圖如下:

          左邊是基礎(chǔ),右邊是方案,如果你也在學(xué)習(xí)分布式事務(wù)相關(guān)知識(shí),可以參考。

          本文是系列第一篇,后面計(jì)劃一篇為seata實(shí)戰(zhàn),一篇為seata原理和如何設(shè)計(jì)一個(gè)通用分布式事務(wù)框架。感謝閱讀,歡迎關(guān)注。

          — 【 THE END 】—
          本公眾號(hào)全部博文已整理成一個(gè)目錄,請(qǐng)?jiān)诠娞?hào)里回復(fù)「m」獲?。?/span>


          3T技術(shù)資源大放送!包括但不限于:Java、C/C++,Linux,Python,大數(shù)據(jù),人工智能等等。在公眾號(hào)內(nèi)回復(fù)「1024」,即可免費(fèi)獲?。?!





          瀏覽 17
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  亚洲 精品一区二区三区 | 亚洲视频在线观看免费观看 | 中国女人真人一级毛片 | 苍井空一二区 | 十八毛片18女人18毛片 |