漫话:如何给女朋友解释什么是2PC(二阶段提交)?
周末晚上,正在家里面看綜藝節(jié)目,突然女朋友跑過來找我打《王者榮耀》。
打了幾把游戲,終于可以歇息一會了,準(zhǔn)備繼續(xù)看我的綜藝,可是女朋友過來找我給他講講到底什么是二階段提交。
分布式一致性
還好我們之前專門給女朋友介紹過什么是分布式,要不然這個(gè)話題說來就話長了。
在之前介紹分布式的時(shí)候,我們以飯店的后廚為例,今天繼續(xù)之前的例子來說說什么是分布式一致性。
隨著飯店的發(fā)展,慢慢的從只有一個(gè)廚師演變成有多個(gè)廚師,進(jìn)而演變成有洗菜工、配菜師、廚師等多個(gè)職位。
當(dāng)有了多種分工之后,就勢必需要協(xié)調(diào)這些人之間的合作。
比如餐廳客人點(diǎn)了一份番茄炒蛋,然后后廚開始準(zhǔn)備起來,洗菜工開始洗西紅柿,配菜師開始準(zhǔn)備雞蛋,廚師開始向鍋內(nèi)加油準(zhǔn)備炒菜。這是一種很正常的情況。
但是,如果消息傳達(dá)的不到位,或者洗菜師傅臨時(shí)不在廚房等,就會導(dǎo)致有的人已經(jīng)開始準(zhǔn)備起來,但是有的人并沒有準(zhǔn)備。
這就像是一個(gè)分布式系統(tǒng)一樣的,當(dāng)我們在電商網(wǎng)站下單的時(shí)候,需要有多個(gè)分布式服務(wù)同時(shí)服務(wù),如支付系統(tǒng)進(jìn)行支付、紅包系統(tǒng)進(jìn)行紅包扣減、庫存系統(tǒng)扣減庫存、物流系統(tǒng)更新物流信息等。
但是,如果其中某一個(gè)系統(tǒng)在執(zhí)行過程中失敗了,或者由于網(wǎng)絡(luò)原因沒有收到請求,那么,整個(gè)系統(tǒng)可能就有不一致的現(xiàn)象了,即:付了錢,扣了紅包,但是庫存沒有扣減。
這就是所謂的分布式系統(tǒng)的數(shù)據(jù)一致性問題。
二階段提交
之所以剛剛的例子中會出現(xiàn)一致性問題,就是因?yàn)槊恳粋€(gè)員工都只關(guān)注自己所做的事情,無法關(guān)注到其他人,那么,要想保證整體的一致性,就需要在后廚中引入一個(gè)新的角色,負(fù)責(zé)統(tǒng)籌,這個(gè)角色來進(jìn)行協(xié)調(diào)和調(diào)配所有人。
那么,引入一個(gè)協(xié)調(diào)者負(fù)責(zé)協(xié)調(diào)所有參與者的工作,這個(gè)在分布式系統(tǒng)中其實(shí)就是X/Open組織定義的分布式事務(wù)處理模型,而二階段提交就是根據(jù)這一模型衍生出來的。
舉個(gè)例子,五個(gè)人相約打王者榮耀,想要一起玩需要以下幾個(gè)步驟:
有一個(gè)人想要五黑玩王者榮耀,于是他開始聯(lián)系自己的小伙伴們。
組織者:小A,我們準(zhǔn)備玩王者榮耀,你要是可以來參加的話,現(xiàn)在你就登錄游戲,然后在游戲好友上給我回復(fù)個(gè)消息。
小A登錄自己的游戲賬號,然后告訴組織者:小A已就位。
組織者:小B、小C、小D,我們準(zhǔn)備玩王者榮耀,你要是可以來參加的話,現(xiàn)在你就登錄游戲,然后在游戲好友上給我回復(fù)個(gè)消息。
小B、小C、小D分別登錄自己的游戲賬號,然后告訴組織者:小B、小C、小D已就位。
組織者發(fā)現(xiàn)所有人都就位了,于是在游戲上逐一通知大家,
組織者:小A,我邀請你了,你進(jìn)來吧。
小A接受邀請
組織者:小B、小C、小D,我邀請你了,你進(jìn)來吧。
小小B、小C、小D接收邀請
于是,5個(gè)人在王者峽谷愉快的玩耍了起來。
對于五個(gè)人開黑這個(gè)事務(wù)操作,在開始準(zhǔn)備前五個(gè)人都是空閑狀態(tài),忙著自己的事情。在組織者協(xié)調(diào)過之后,大家也要達(dá)成一個(gè)一致的狀態(tài),即以下兩種情況之一:
1、五個(gè)人愉快的開始一起玩游戲
2、五個(gè)人都退出游戲,還是去忙自己的事情。
如果最后有一部分人在游戲里一直等,另外一部分并沒有進(jìn)入游戲,那么就是數(shù)據(jù)不一致了。
以上過程,就是一個(gè)典型的二階段提交(2PC)的過程,在分布式系統(tǒng)中,也有同樣的問題,并且可以采用同樣的解決辦法。
在分布式系統(tǒng)中,每個(gè)節(jié)點(diǎn)雖然可以知曉自己的操作時(shí)成功或者失敗,卻無法知道其他節(jié)點(diǎn)的操作的成功或失敗(只知道自己有時(shí)間可以玩王者榮耀,不知道其他人有沒有)。
當(dāng)一個(gè)事務(wù)跨越多個(gè)節(jié)點(diǎn)時(shí),為了保持事務(wù)的ACID特性,需要引入一個(gè)作為協(xié)調(diào)者的組件來統(tǒng)一掌控所有參與者的操作結(jié)果并最終指示這些節(jié)點(diǎn)是否要把操作結(jié)果進(jìn)行真正的提交(組織者通知各位參與者一起進(jìn)入游戲房間)。
因此,二階段提交的算法思路可以概括為:參與者將操作成敗通知協(xié)調(diào)者,再由協(xié)調(diào)者根據(jù)所有參與者的反饋情報(bào)決定各參與者是否要提交操作還是中止操作。
所謂的兩個(gè)階段是指:第一階段:準(zhǔn)備階段(投票階段)和第二階段:提交階段(執(zhí)行階段)
準(zhǔn)備階段
事務(wù)協(xié)調(diào)者給每個(gè)參與者發(fā)送Prepare消息,每個(gè)參與者要么直接返回失敗(告知組織者自己沒時(shí)間,不能一起玩游戲),要么在本地執(zhí)行事務(wù)(登錄王者榮耀),但不提交(先不開始游戲)。
可以進(jìn)一步將準(zhǔn)備階段分為以下三個(gè)步驟:
1)協(xié)調(diào)者節(jié)點(diǎn)向所有參與者節(jié)點(diǎn)詢問是否可以執(zhí)行提交操作,并開始等待各參與者節(jié)點(diǎn)的響應(yīng)。(詢問是否可以一起玩游戲)
2)參與者節(jié)點(diǎn)執(zhí)行詢問發(fā)起為止的所有事務(wù)操作,并將Undo信息和Redo信息寫入日志。(登錄王者榮耀游戲)
3)各參與者節(jié)點(diǎn)響應(yīng)協(xié)調(diào)者節(jié)點(diǎn)發(fā)起的詢問。如果參與者節(jié)點(diǎn)的事務(wù)操作實(shí)際執(zhí)行成功,則它返回一個(gè)”同意”消息;(告知組織者自己已經(jīng)登錄成功)如果參與者節(jié)點(diǎn)的事務(wù)操作實(shí)際執(zhí)行失敗,則它返回一個(gè)”中止”消息。(告知組織者自己暫時(shí)無法一起玩游戲,如自己的賬號被限制無法打排位)
提交階段
如果協(xié)調(diào)者收到了參與者的失敗消息或者超時(shí)(有人不能一起玩游戲,或者一直沒有回復(fù)),直接給每個(gè)參與者發(fā)送回滾消息(告知其他人,暫時(shí)取消游戲);否則,發(fā)送提交消息(邀請大家進(jìn)入游戲房間);參與者根據(jù)協(xié)調(diào)者的指令執(zhí)行提交或者回滾操作(進(jìn)入房間一起玩游戲或者退出游戲去做別的事情)。
接下來分兩種情況分別討論提交階段的過程。
當(dāng)協(xié)調(diào)者節(jié)點(diǎn)從所有參與者節(jié)點(diǎn)獲得的相應(yīng)消息都為”同意”時(shí):
1)協(xié)調(diào)者節(jié)點(diǎn)向所有參與者節(jié)點(diǎn)發(fā)出”正式提交”的請求(要求所有已登錄的朋友加入游戲房間)。
2)參與者節(jié)點(diǎn)正式完成操作,并釋放在整個(gè)事務(wù)期間內(nèi)占用的資源(接受邀請,進(jìn)入房間)。
3)參與者節(jié)點(diǎn)向協(xié)調(diào)者節(jié)點(diǎn)發(fā)送”完成”消息(點(diǎn)擊"準(zhǔn)備",進(jìn)入準(zhǔn)備狀態(tài))。
4)協(xié)調(diào)者節(jié)點(diǎn)受到所有參與者節(jié)點(diǎn)反饋的”完成”消息后,完成事務(wù)(進(jìn)入王者峽谷)。
如果任一參與者節(jié)點(diǎn)在第一階段返回的響應(yīng)消息為”中止”,或者 協(xié)調(diào)者節(jié)點(diǎn)在第一階段的詢問超時(shí)之前無法獲取所有參與者節(jié)點(diǎn)的響應(yīng)消息時(shí):
1)協(xié)調(diào)者節(jié)點(diǎn)向所有參與者節(jié)點(diǎn)發(fā)出”回滾操作”的請求(告知所有人取消游戲)。
2)參與者節(jié)點(diǎn)利用之前寫入的Undo信息執(zhí)行回滾,并釋放在整個(gè)事務(wù)期間內(nèi)占用的資源(退出游戲,去做自己的事情)。
3)參與者節(jié)點(diǎn)向協(xié)調(diào)者節(jié)點(diǎn)發(fā)送”回滾完成”消息(告訴組織者自己知道了,后面有機(jī)會再玩)。
4)協(xié)調(diào)者節(jié)點(diǎn)受到所有參與者節(jié)點(diǎn)反饋的”回滾完成”消息后,取消事務(wù)(取消本次游戲活動)。
2PC的缺點(diǎn)
以上過程其實(shí)是有一些缺點(diǎn)的,如
1、當(dāng)參與者收到組織者的消息之后,需要登錄游戲,在游戲中等待組織者的再次邀請,這個(gè)過程比較浪費(fèi)時(shí)間。
2、如果在這個(gè)過程中,組織者突然有什么事情被打斷了,那么那些已經(jīng)進(jìn)入游戲的參與者就可能一直等下去。
3、在所有人都登錄游戲之后,組織者通過邀請要求所有人加入他的房間,這時(shí)候如果有一些網(wǎng)絡(luò)異常、或者參與者沒在手機(jī)前面等情況,可能會有一部分用戶加入了房間,有一部分沒加入。
4、如果組織者在游戲中開始邀請所有參與者的時(shí)候,他邀請了第一個(gè)人之后,他和這個(gè)被他邀請的人都掉線了。這時(shí)候另外三個(gè)人就不知道到底應(yīng)該怎么辦了。
以上問題,分布式系統(tǒng)的2PC階段一樣存在,分別對應(yīng)以下問題:
1、同步阻塞問題。執(zhí)行過程中,所有參與節(jié)點(diǎn)都是事務(wù)阻塞型的。當(dāng)參與者占有公共資源時(shí),其他第三方節(jié)點(diǎn)訪問公共資源不得不處于阻塞狀態(tài)。
2、單點(diǎn)故障。由于協(xié)調(diào)者的重要性,一旦協(xié)調(diào)者發(fā)生故障。參與者會一直阻塞下去。尤其在第二階段,協(xié)調(diào)者發(fā)生故障,那么所有的參與者還都處于鎖定事務(wù)資源的狀態(tài)中,而無法繼續(xù)完成事務(wù)操作。(如果是協(xié)調(diào)者掛掉,可以重新選舉一個(gè)協(xié)調(diào)者,但是無法解決因?yàn)閰f(xié)調(diào)者宕機(jī)導(dǎo)致的參與者處于阻塞狀態(tài)的問題)
3、數(shù)據(jù)不一致。在二階段提交的階段二中,當(dāng)協(xié)調(diào)者向參與者發(fā)送commit請求之后,發(fā)生了局部網(wǎng)絡(luò)異常或者在發(fā)送commit請求過程中協(xié)調(diào)者發(fā)生了故障,這回導(dǎo)致只有一部分參與者接受到了commit請求。而在這部分參與者接到commit請求之后就會執(zhí)行commit操作。但是其他部分未接到commit請求的機(jī)器則無法執(zhí)行事務(wù)提交。于是整個(gè)分布式系統(tǒng)便出現(xiàn)了數(shù)據(jù)部一致性的現(xiàn)象。
4、二階段無法解決的問題:協(xié)調(diào)者再發(fā)出commit消息之后宕機(jī),而唯一接收到這條消息的參與者同時(shí)也宕機(jī)了。那么即使協(xié)調(diào)者通過選舉協(xié)議產(chǎn)生了新的協(xié)調(diào)者,這條事務(wù)的狀態(tài)也是不確定的,沒人知道事務(wù)是否被已經(jīng)提交。
總結(jié)一下,就是說2PC并不是完美的,他存在著同步阻塞問題、單點(diǎn)故障問題、無法100%保證數(shù)據(jù)一致性等問題。
有道無術(shù),術(shù)可成;有術(shù)無道,止于術(shù)
歡迎大家關(guān)注Java之道公眾號
好文章,我在看??
總結(jié)
以上是生活随笔為你收集整理的漫话:如何给女朋友解释什么是2PC(二阶段提交)?的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 不想被时代抛弃,就别远离一线
- 下一篇: 如何在RCP程序中添加一个banner栏