在分布式系統(tǒng)中,著有CAP理論睛约,該理論由加州大學(xué)伯克利分校的Eric Brewer教授提出,該理論闡述了在一個(gè)分布式系統(tǒng)中不可能同時(shí)滿足一致性(Consistency)、可用性(Availability)探孝,以及分區(qū) 容錯(cuò)性(Partition tolerance)。
- 一致性
在分布式系統(tǒng)中數(shù)據(jù)往往存在多個(gè)副本誉裆,一致性描述的是這些副本中的數(shù)據(jù)在內(nèi)容和組織上的一致顿颅。 - 可用性
可用性描述了系統(tǒng)對(duì)用戶的服務(wù)能力,所謂可用是指在用戶容忍的時(shí)間范圍內(nèi)返回用戶期望的結(jié)果足丢。 - 分區(qū)容錯(cuò)性
分布式系統(tǒng)通常由多個(gè)節(jié)點(diǎn)構(gòu)成粱腻,這些節(jié)點(diǎn)通常分布在不同的網(wǎng)絡(luò)中,然而網(wǎng)絡(luò)始終是不可靠的斩跌,所以存在分布式集群中的節(jié)點(diǎn)因?yàn)榫W(wǎng)絡(luò)通信故障導(dǎo)致被孤立成一個(gè)個(gè)小集群的可能性绍些,分區(qū)容錯(cuò)性要求在出現(xiàn)這種情況下系統(tǒng)仍然能夠?qū)ν馓峁┮恢滦缘目捎梅?wù)。
對(duì)于一個(gè)分布式系統(tǒng)耀鸦,我們始終要假設(shè)網(wǎng)絡(luò)是不可靠的柬批,所以分區(qū)容錯(cuò)性是對(duì)一個(gè)分布式系統(tǒng)最基本的要求,所以我們更多的是嘗試在可用性和一致性之 間尋找一個(gè)平衡點(diǎn)揭糕。讓分布式集群始終對(duì)外提供可用的一致性服務(wù)一直是富有挑戰(zhàn)和趣味的一項(xiàng)任務(wù)萝快。暫且拋開可用性,拿一致性來說著角,對(duì)于關(guān)系型數(shù)據(jù)庫我們通常 利用事務(wù)來保證數(shù)據(jù)的一致性揪漩,當(dāng)我們的數(shù)據(jù)量越來越大,大到單庫已經(jīng)無法承擔(dān)時(shí)吏口,我們不得不采取分庫分表的策略對(duì)數(shù)據(jù)庫實(shí)現(xiàn)拆分奄容,構(gòu)建分布式數(shù)據(jù)庫集群, 這樣可以將一個(gè)數(shù)據(jù)庫的壓力分?jǐn)偟蕉鄠€(gè)數(shù)據(jù)庫产徊,極大的提升了數(shù)據(jù)庫的存儲(chǔ)和響應(yīng)能力昂勒,但是也為我們使用數(shù)據(jù)庫帶來了許多的限制,比如主鍵的全局唯一舟铜、聯(lián)表 查詢戈盈、數(shù)據(jù)聚合等等,另外一個(gè)相當(dāng)棘手的問題就是數(shù)據(jù)庫的事務(wù)由原先的單庫事務(wù)變成了現(xiàn)在的分布式事務(wù)。
??分布式事務(wù)的實(shí)現(xiàn)并不是很難塘娶,比如下 文要展開的兩階段提交(2PC:Two-Phrase Commit)和三階段提交(3PC:Three-Phrase Commit)都給我們提供了思路归斤,但是如果要保證數(shù)據(jù)的強(qiáng)一致性,并要求對(duì)外提供可用的服務(wù)刁岸,那么就變成了一個(gè)幾乎不可能的任務(wù)(至少目前是)脏里,因此很 多分布式系統(tǒng)對(duì)于數(shù)據(jù)強(qiáng)一致性都敬而遠(yuǎn)之,本人在之前項(xiàng)目的架構(gòu)設(shè)計(jì)中也花費(fèi)不少時(shí)間在系統(tǒng)的一致性和可用性之間尋找平衡虹曙。
兩階段提交協(xié)議(2PC:Two-Phrase Commit)
兩階段提交協(xié)議的目標(biāo)在于在分布式系統(tǒng)中保證數(shù)據(jù)的一致性迫横,許多分布式系統(tǒng)采用該協(xié)議提供對(duì)分布式事務(wù)的支持(提供但不一定有人用,呵呵~)酝碳。 顧名思義矾踱,該協(xié)議將一個(gè)分布式的事務(wù)過程拆分成兩個(gè)階段:投票階段和事務(wù)提交階段。為了讓整個(gè)數(shù)據(jù)庫集群能夠正常的運(yùn)行击敌,該協(xié)議指定了一個(gè)“協(xié)調(diào)者”單 點(diǎn)介返,用于協(xié)調(diào)整個(gè)數(shù)據(jù)庫集群的運(yùn)行,為了簡(jiǎn)化描述沃斤,我們將數(shù)據(jù)庫里面的各個(gè)節(jié)點(diǎn)稱為“參與者”圣蝎,三階段提交協(xié)議中同樣包含“協(xié)調(diào)者”和“參與者”這兩個(gè)定 義。
第一階段:投票階段
該階段的主要目的在于打探數(shù)據(jù)庫集群中的各個(gè)參與者是否能夠正常的執(zhí)行事務(wù)衡瓶,具體步驟如下:
1. 協(xié)調(diào)者向所有的參與者發(fā)送事務(wù)執(zhí)行請(qǐng)求徘公,并等待參與者反饋事務(wù)執(zhí)行結(jié)果。
2. 事務(wù)參與者收到請(qǐng)求之后哮针,執(zhí)行事務(wù)关面,但不提交,并記錄事務(wù)日志十厢。
3. 參與者將自己事務(wù)執(zhí)行情況反饋給協(xié)調(diào)者等太,同時(shí)阻塞等待協(xié)調(diào)者的后續(xù)指令。
第二階段:事務(wù)提交階段
在第一階段協(xié)調(diào)者的詢盤之后蛮放,各個(gè)參與者會(huì)回復(fù)自己事務(wù)的執(zhí)行情況缩抡,這時(shí)候存在三種可能:
1. 所有的參與者回復(fù)能夠正常執(zhí)行事務(wù)
2. 一個(gè)或多個(gè)參與者回復(fù)事務(wù)執(zhí)行失敗
3. 協(xié)調(diào)者等待超時(shí)。
對(duì)于第一種情況包颁,協(xié)調(diào)者將向所有的參與者發(fā)出提交事務(wù)的通知瞻想,具體步驟如下:
1. 協(xié)調(diào)者向各個(gè)參與者發(fā)送commit通知,請(qǐng)求提交事務(wù)娩嚼。
2. 參與者收到事務(wù)提交通知之后蘑险,執(zhí)行commit操作,然后釋放占有的資源岳悟。
3. 參與者向協(xié)調(diào)者返回事務(wù)commit結(jié)果信息佃迄。
對(duì)于第二、三種情況,協(xié)調(diào)者均認(rèn)為參與者無法正常成功執(zhí)行事務(wù)呵俏,為了整個(gè)集群數(shù)據(jù)的一致性拴驮,所以要向各個(gè)參與者發(fā)送事務(wù)回滾通知,具體步驟如下:
1. 協(xié)調(diào)者向各個(gè)參與者發(fā)送事務(wù)rollback通知柴信,請(qǐng)求回滾事務(wù)。
2. 參與者收到事務(wù)回滾通知之后宽气,執(zhí)行rollback操作随常,然后釋放占有的資源。
3. 參與者向協(xié)調(diào)者返回事務(wù)rollback結(jié)果信息萄涯。
兩階段提交協(xié)議解決的是分布式數(shù)據(jù)庫數(shù)據(jù)強(qiáng)一致性問題绪氛,其原理簡(jiǎn)單,易于實(shí)現(xiàn)涝影,但是缺點(diǎn)也是顯而易見的枣察,主要缺點(diǎn)如下:
單點(diǎn)問題
協(xié)調(diào)者在整個(gè)兩階段提交過程中扮演著舉足輕重的作用,一旦協(xié)調(diào)者所在服務(wù)器宕機(jī)燃逻,那么就會(huì)影響整個(gè)數(shù)據(jù)庫集群的正常運(yùn)行序目,比如在第二階段中,如果協(xié)調(diào)者因?yàn)楣收喜荒苷0l(fā)送事務(wù)提交或回滾通知伯襟,那么參與者們將一直處于阻塞狀態(tài)猿涨,整個(gè)數(shù)據(jù)庫集群將無法提供服務(wù)。同步阻塞
兩階段提交執(zhí)行過程中姆怪,所有的參與者都需要聽從協(xié)調(diào)者的統(tǒng)一調(diào)度叛赚,期間處于阻塞狀態(tài)而不能從事其他操作,這樣效率及其低下稽揭。數(shù)據(jù)不一致性
兩階段提交協(xié)議雖然為分布式數(shù)據(jù)強(qiáng)一致性所設(shè)計(jì)俺附,但仍然存在數(shù)據(jù)不一致性的可能,比如在第二階段中溪掀,假設(shè)協(xié)調(diào)者發(fā)出了 事務(wù)commit的通知事镣,但是因?yàn)榫W(wǎng)絡(luò)問題該通知僅被一部分參與者所收到并執(zhí)行了commit操作,其余的參與者則因?yàn)闆]有收到通知一直處于阻塞狀態(tài)膨桥,這 時(shí)候就產(chǎn)生了數(shù)據(jù)的不一致性蛮浑。
三階段提交協(xié)議(2PC:Three-Phrase Commit)
針對(duì)兩階段提交存在的問題,三階段提交協(xié)議通過引入一個(gè)“預(yù)詢盤”階段只嚣,以及超時(shí)策略來減少整個(gè)集群的阻塞時(shí)間沮稚,提升系統(tǒng)性能。三階段提交的三個(gè)階段分別為:can_commit册舞,pre_commit蕴掏,do_commit。
第一階段:can_commit
該階段協(xié)調(diào)者會(huì)去詢問各個(gè)參與者是否能夠正常執(zhí)行事務(wù),參與者根據(jù)自身情況回復(fù)一個(gè)預(yù)估值盛杰,相對(duì)于真正的執(zhí)行事務(wù)挽荡,這個(gè)過程是輕量的,具體步驟如下:
1. 協(xié)調(diào)者向各個(gè)參與者發(fā)送事務(wù)詢問通知即供,詢問是否可以執(zhí)行事務(wù)操作定拟,并等待回復(fù)
2. 各個(gè)參與者依據(jù)自身狀況回復(fù)一個(gè)預(yù)估值,如果預(yù)估自己能夠正常執(zhí)行事務(wù)就返回確定信息逗嫡,并進(jìn)入預(yù)備狀態(tài)青自,否則返回否定信息
第二階段:pre_commit
本階段協(xié)調(diào)者會(huì)根據(jù)第一階段的詢盤結(jié)果采取相應(yīng)操作,詢盤結(jié)果主要有三種:
1. 所有的參與者都返回確定信息
2. 一個(gè)或多個(gè)參與者返回否定信息
3. 協(xié)調(diào)者等待超時(shí)
針對(duì)第一種情況驱证,協(xié)調(diào)者會(huì)向所有參與者發(fā)送事務(wù)執(zhí)行請(qǐng)求延窜,具體步驟如下:
1. 協(xié)調(diào)者向所有的事務(wù)參與者發(fā)送事務(wù)執(zhí)行通知
2. 參與者收到通知后,執(zhí)行事務(wù)抹锄,但不提交
3. 參與者將事務(wù)執(zhí)行情況返回給客戶端
在上面的步驟中逆瑞,如果參與者等待超時(shí),則會(huì)中斷事務(wù)伙单。 針對(duì)第二获高、三種情況,協(xié)調(diào)者認(rèn)為事務(wù)無法正常執(zhí)行吻育,于是向各個(gè)參與者發(fā)出abort通知谋减,請(qǐng)求退出預(yù)備狀態(tài),具體步驟如下:
1. 協(xié)調(diào)者向所有事務(wù)參與者發(fā)送abort通知
2. 參與者收到通知后扫沼,中斷事務(wù)
第三階段:do_commit
如果第二階段事務(wù)未中斷出爹,那么本階段協(xié)調(diào)者將會(huì)依據(jù)事務(wù)執(zhí)行返回的結(jié)果來決定提交或回滾事務(wù),分為三種情況:
1. 所有的參與者都能正常執(zhí)行事務(wù)
2. 一個(gè)或多個(gè)參與者執(zhí)行事務(wù)失敗
3. 協(xié)調(diào)者等待超時(shí)
針對(duì)第一種情況缎除,協(xié)調(diào)者向各個(gè)參與者發(fā)起事務(wù)提交請(qǐng)求严就,具體步驟如下:
1. 協(xié)調(diào)者向所有參與者發(fā)送事務(wù)commit通知
2. 所有參與者在收到通知之后執(zhí)行commit操作,并釋放占有的資源
3. 參與者向協(xié)調(diào)者反饋事務(wù)提交結(jié)果
針對(duì)第二器罐、三種情況梢为,協(xié)調(diào)者認(rèn)為事務(wù)無法正常執(zhí)行,于是向各個(gè)參與者發(fā)送事務(wù)回滾請(qǐng)求轰坊,具體步驟如下:
1. 協(xié)調(diào)者向所有參與者發(fā)送事務(wù)rollback通知
2. 所有參與者在收到通知之后執(zhí)行rollback操作铸董,并釋放占有的資源
3. 參與者向協(xié)調(diào)者反饋事務(wù)提交結(jié)果
在本階段如果因?yàn)閰f(xié)調(diào)者或網(wǎng)絡(luò)問題,導(dǎo)致參與者遲遲不能收到來自協(xié)調(diào)者的commit或rollback請(qǐng)求肴沫,那么參與者將不會(huì)如兩階段提交中那樣陷入阻塞粟害,而是等待超時(shí)后繼續(xù)commit。相對(duì)于兩階段提交雖然降低了同步阻塞颤芬,但仍然無法避免數(shù)據(jù)的不一致性悲幅。
在分布式數(shù)據(jù)庫中套鹅,如果期望達(dá)到數(shù)據(jù)的強(qiáng)一致性,那么服務(wù)基本沒有可用性可言汰具,這也是為什么許多分布式數(shù)據(jù)庫提供了跨庫事務(wù)卓鹿,但也只是個(gè)擺設(shè)的原因,在實(shí)際應(yīng)用中我們更多追求的是數(shù)據(jù)的弱一致性或最終一致性留荔,為了強(qiáng)一致性而丟棄可用性是不可取的吟孙。