前言
本文編寫的目的:為了深入理解后期關(guān)于zookeeper的文章,本文這里對(duì)分布式一致性算法的由來(lái)以及要解決的問(wèn)題做一個(gè)簡(jiǎn)述,更加深入的原理性東西后續(xù)將會(huì)以專輯的形式撰寫。另該文比較長(zhǎng),建議收藏閱讀
本文編寫的順序:從集中式演化到分布式--->分布式出現(xiàn)的一些問(wèn)題--->如何解決這些問(wèn)題(即最重要的一致性問(wèn)題)---->事務(wù)(保證一致性的方法)---->從早期的ACID到CAP/BASE理論---->2pc/3pc----->Paxos算法
背景
20世紀(jì)60年代大型主機(jī)被發(fā)明出來(lái)以后,集中式的計(jì)算機(jī)系統(tǒng)架構(gòu)成為了主流,其單機(jī)處理能力方面的優(yōu)勢(shì)非常明顯,但從20世紀(jì)80年代之后,傳統(tǒng)的集中式處理模式越來(lái)越不能滿足人們的需求,同時(shí)集中式系統(tǒng)有明顯的單點(diǎn)故障問(wèn)題,從2008年開始,阿里開啟了“去IOE”計(jì)劃,后來(lái)逐漸的往分布式系統(tǒng)的方向發(fā)展。
分布式系統(tǒng)是一個(gè)硬件或軟件組件分布在不同的網(wǎng)絡(luò)計(jì)算機(jī)上,彼此之間僅僅通過(guò)消息傳遞進(jìn)行通信和協(xié)調(diào)的系統(tǒng)。因此分布式系統(tǒng)具有以下幾個(gè)特點(diǎn):
1.分布性
多臺(tái)計(jì)算機(jī)在空間上隨意分布,同時(shí)分布情況也會(huì)隨時(shí)變動(dòng)
2.對(duì)等性
集群中的每個(gè)節(jié)點(diǎn)角色都是一樣的,注意副本的概念
3.并發(fā)性
多個(gè)機(jī)器可能會(huì)同時(shí)操作一個(gè)數(shù)據(jù)庫(kù)或存儲(chǔ)系統(tǒng),可能會(huì)引起數(shù)據(jù)不一致問(wèn)題
4.缺乏全局時(shí)鐘
分布式系統(tǒng)中的多個(gè)主機(jī)事件先后順序很難界定
5.故障總發(fā)生
服務(wù)器宕機(jī),網(wǎng)絡(luò)擁堵和延遲
同時(shí)和分布式系統(tǒng)進(jìn)行對(duì)比發(fā)現(xiàn)集中式系統(tǒng)具有以下幾個(gè)特點(diǎn):
部署結(jié)構(gòu)簡(jiǎn)單
成本高
單點(diǎn)故障
大型主機(jī)的性能擴(kuò)展受限于摩爾定律
注意:這里要區(qū)分集群和分布式的概念,集群是指大量的機(jī)器做同一件事情;分布式是指每臺(tái)機(jī)器都有不同的角色,做不同的事情
分布式異常問(wèn)題
分布式系統(tǒng)體系結(jié)構(gòu)從出現(xiàn)到現(xiàn)在仍有很多的問(wèn)題,這里列出一些典型的問(wèn)題
1.通信異常
從集中式向分布式演變,必然會(huì)引入網(wǎng)絡(luò)因素,由于網(wǎng)絡(luò)的不可靠性,必然會(huì)在分布式節(jié)點(diǎn)之間出現(xiàn)網(wǎng)絡(luò) 異常的情況
2.網(wǎng)絡(luò)分區(qū)
網(wǎng)絡(luò)分區(qū)也就是常說(shuō)的腦裂,即出現(xiàn)多個(gè)局部小集群,每個(gè)局部網(wǎng)絡(luò)可以互相通信
3.三態(tài)
三態(tài)指的是三種狀態(tài),即成功、失敗、超時(shí);在集中式系統(tǒng)中只有成功和失敗,而超時(shí)是由于分布式系統(tǒng)中會(huì)出現(xiàn)網(wǎng)絡(luò)異常才會(huì)有的狀態(tài)
4.節(jié)點(diǎn)故障
分布式節(jié)點(diǎn)總會(huì)出現(xiàn)宕機(jī)或者僵死現(xiàn)象
5.數(shù)據(jù)丟失
對(duì)于有狀態(tài)的節(jié)點(diǎn),數(shù)據(jù)丟失意味著狀態(tài)丟失,通常只能從其他節(jié)點(diǎn)讀取,恢復(fù)存儲(chǔ)的狀態(tài);通常針對(duì)這種問(wèn)題,通過(guò)引入副本機(jī)制就可以解決
衡量分布式系統(tǒng)的性能
性能
即系統(tǒng)吞吐能力、響應(yīng)延遲、QPS等
可用性
可擴(kuò)展性
一致性
一致性模型
分布式環(huán)境下,一致性指的是數(shù)據(jù)在多個(gè)副本之間是否能夠保持一致的特性,對(duì)于一個(gè)將數(shù)據(jù)副本分布在不同節(jié)點(diǎn)的系統(tǒng)上來(lái)說(shuō),如果對(duì)一個(gè)節(jié)點(diǎn)的數(shù)據(jù)進(jìn)行了更新操作,卻沒(méi)有使得第二個(gè)節(jié)點(diǎn)上的數(shù)據(jù)得到響應(yīng)的更新,那么此時(shí)在讀取第二個(gè)節(jié)點(diǎn)的數(shù)據(jù)時(shí),將會(huì)出現(xiàn)臟讀現(xiàn)象(即數(shù)據(jù)不一致).那么一致性又分為以下幾種:
強(qiáng)一致性
即寫操作完成后,讀操作一定能夠讀到最新的數(shù)據(jù),在分布式場(chǎng)景下,很難實(shí)現(xiàn);Paxos、Quorum機(jī)制、ZAB協(xié)議能夠?qū)崿F(xiàn),后面會(huì)對(duì)這幾種協(xié)議算法進(jìn)行講解。
弱一致性
不承諾立即可以讀到寫入的值,也不承諾多久后能達(dá)到數(shù)據(jù)一致,但會(huì)盡可能保證某個(gè)時(shí)間級(jí)別后,數(shù)據(jù)達(dá)到一致狀態(tài)
讀寫一致性
用戶讀取自己寫入結(jié)果的一致性,保證用戶能夠第一時(shí)間看到自己更新的內(nèi)容;這種實(shí)現(xiàn)的解決方案有:一種方案是對(duì)于特定的內(nèi)容,我們?nèi)ブ鲙?kù)查詢
設(shè)置一個(gè)更新時(shí)間窗口,在剛更新的一段時(shí)間內(nèi),默認(rèn)去主庫(kù)讀取,過(guò)了這個(gè)窗口后,挑選最近更新的從庫(kù)進(jìn)行讀取
直接記錄用戶更新的時(shí)間戳,在請(qǐng)求的時(shí)候把這個(gè)時(shí)間戳帶上,凡是最后更新時(shí)間小于這個(gè)時(shí)間戳的從庫(kù)都不響應(yīng)
單調(diào)讀一致性
本地讀到的數(shù)據(jù)不比上次讀到的舊,多次刷新返回舊數(shù)據(jù)會(huì)出現(xiàn)靈異事件,對(duì)于這種情況可以通過(guò)hash映射到同一臺(tái)機(jī)器上
因果一致性
如果節(jié)點(diǎn)A在更新完某個(gè)數(shù)據(jù)后通知了節(jié)點(diǎn)B,那么節(jié)點(diǎn)B之后對(duì)該數(shù)據(jù)的訪問(wèn)和修改基于A更新的值。此時(shí),和節(jié)點(diǎn)A無(wú)因果關(guān)系的節(jié)點(diǎn)C的數(shù)據(jù)訪問(wèn)則沒(méi)有這樣的限制
最終一致性
所有分布式一致性模型中最弱的。不考慮中間的任何狀態(tài),只保證經(jīng)過(guò)一段時(shí)間之后,最終系統(tǒng)內(nèi)數(shù)據(jù)正確,最大程度上保證了系統(tǒng)的并發(fā)能力,因此在高并發(fā)場(chǎng)景下,也是使用最廣的一致性模型
事務(wù)
事務(wù)是可以保證一致性的方法,在集中式系統(tǒng)架構(gòu)中可以通過(guò)ACID的方式實(shí)現(xiàn),在早期分布式架構(gòu),是通過(guò)CAP/BASE理論來(lái)實(shí)現(xiàn)的,后來(lái)又演化出了2pc/3pc,以及Paxos、Raft等算法來(lái)保證一致性。
事務(wù)是由一系列對(duì)系統(tǒng)中數(shù)據(jù)進(jìn)行訪問(wèn)與更新的操作所組成的一個(gè)程序執(zhí)行邏輯單元。(概念性的東西直接略過(guò)~)
- ACID
- Atomicity原子性簡(jiǎn)單說(shuō)就是一個(gè)操作序列要么全部成功執(zhí)行,要么全部不執(zhí)行
- Consistency一致性也就是說(shuō)數(shù)據(jù)從一個(gè)一致性狀態(tài)轉(zhuǎn)變到另一個(gè)一致性狀態(tài),中間不能存在不一致的狀態(tài)
- Isolation隔離性在并發(fā)環(huán)境下,一個(gè)事務(wù)的執(zhí)行不能被其他事務(wù)所干擾,每個(gè)事務(wù)都有各自獨(dú)立完整的數(shù)據(jù)空間,也就是說(shuō)一個(gè)事務(wù)內(nèi)部的操作以及數(shù)據(jù)的使用對(duì)其他并發(fā)的事務(wù)都是隔離的。根據(jù)隔離性的強(qiáng)度分為4個(gè)級(jí)別:
- 未授權(quán)讀取(讀未提交)這是隔離級(jí)別最低的。比如說(shuō)事務(wù)A和事務(wù)B同時(shí)進(jìn)行,事務(wù)A在整個(gè)執(zhí)行的過(guò)程中,會(huì)將某個(gè)數(shù)據(jù)值從1開始做加法操作直到變成10之后提交事務(wù),而此時(shí)事務(wù)B能夠看到事務(wù)A操作這個(gè)數(shù)據(jù)的所有變化(即從1到10的變化),而這一系列中間值的讀取就是未授權(quán)讀取
- 授權(quán)讀取(讀已提交)只允許讀取已經(jīng)被提交的數(shù)據(jù)而且不可重復(fù)讀。比如說(shuō)事務(wù)A和事務(wù)B同時(shí)進(jìn)行,同樣進(jìn)行加法操作(從1到10),那么此時(shí)事務(wù)B是無(wú)法看到所有的中間值,只能看到最終的10.
- 可重復(fù)讀取在保證事務(wù)處理的過(guò)程中,多次讀取同一個(gè)數(shù)據(jù)時(shí)候,它的值和事務(wù)開始時(shí)刻是一致的,可能會(huì)出現(xiàn)幻影數(shù)據(jù)(即同一個(gè)事務(wù)操作,在前后兩個(gè)時(shí)間段內(nèi)執(zhí)行對(duì)同一個(gè)數(shù)據(jù)項(xiàng)進(jìn)行讀取,可能會(huì)得到不同的結(jié)果),還是拿上面的例子,事務(wù)B在第一次事務(wù)讀取的時(shí)候,始終讀到的是1,但是到第二次事務(wù)讀取的時(shí)候就會(huì)變成了10(因?yàn)檫@個(gè)時(shí)候事務(wù)A已經(jīng)完成了)
- 串行化即所有的事務(wù)串行執(zhí)行
- Durability持久性
- 即一個(gè)事務(wù)一旦提交,對(duì)應(yīng)數(shù)據(jù)的狀態(tài)變更就是永久性的
- CAP
- Consistency一致性數(shù)據(jù)在多個(gè)副本之間是否能夠保持一致的特性。
- Avaliabilty可用性指系統(tǒng)提供的服務(wù)必須一直處于可用的狀態(tài),對(duì)于用戶的操作總能給在有限的時(shí)間內(nèi)返回結(jié)果,這里要注意下是在有限的時(shí)間內(nèi)哦
- Partition tolerance分區(qū)容錯(cuò)性即分布式系統(tǒng)在遇到網(wǎng)絡(luò)分區(qū)的時(shí)候,仍然能夠保證對(duì)外提供滿足一致性和可用性的服務(wù),除非整個(gè)網(wǎng)絡(luò)發(fā)生了故障注意:分布式系統(tǒng)無(wú)法滿足上面三個(gè)特性,但是一定要有分布容錯(cuò)性,即P,C和A根據(jù)需求進(jìn)行衡量
- BASE
- Basically Avaliable 基本可用即分布式系統(tǒng)中在出現(xiàn)故障的時(shí)候,允許損失部分可用性,比如響應(yīng)時(shí)間上的損失或者功能上的損失,例如雙11的時(shí)候,可以將一些無(wú)關(guān)緊要的服務(wù)進(jìn)行降級(jí)
- Soft state軟狀態(tài)即允許系統(tǒng)中的數(shù)據(jù)存在中間狀態(tài),且中間狀態(tài)的存在不會(huì)影響系統(tǒng)的整個(gè)可用性,即允許系統(tǒng)在不同節(jié)點(diǎn)的數(shù)據(jù)副本之間進(jìn)行數(shù)據(jù)同步的過(guò)程出現(xiàn)延時(shí)
- Eventually consistent最終一致性強(qiáng)調(diào)的是系統(tǒng)中所有的數(shù)據(jù)副本,在經(jīng)過(guò)一段時(shí)間的同步后,最終達(dá)到一個(gè)一致的狀態(tài)
分布式一致性協(xié)議算法
2pc
即二階段提交,絕大部分的關(guān)系型數(shù)據(jù)庫(kù)都是采用二階段提交協(xié)議來(lái)完成分布式事務(wù)處理。即將事務(wù)的提交過(guò)程分為了兩個(gè)階段來(lái)處理
- 階段一:請(qǐng)求/表決階段
- 1.事務(wù)詢問(wèn)協(xié)調(diào)者向參與者發(fā)起事務(wù)內(nèi)容,詢問(wèn)是否可以執(zhí)行事務(wù)操作,并等待響應(yīng)
- 2.執(zhí)行事務(wù)各參與者執(zhí)行事務(wù)操作,并將undo和redo信息記錄到事務(wù)日志中
- 3.各參與者向協(xié)調(diào)者反饋事務(wù)詢問(wèn)的響應(yīng)協(xié)調(diào)者根據(jù)所有的參與者是否都響應(yīng)了yes或者no來(lái)進(jìn)行表決事務(wù)是否執(zhí)行或者不執(zhí)行
- 階段二:提交/執(zhí)行/回滾階段
- 情況1.執(zhí)行事務(wù)提交
- 1.發(fā)起提交請(qǐng)求協(xié)調(diào)者向參與者發(fā)起commit請(qǐng)求
- 2.事務(wù)提交參與者收到commit請(qǐng)求后,正式執(zhí)行事務(wù)提交,完成之后釋放資源
- 3.反饋事務(wù)提交結(jié)果參與者完成事務(wù)之后,向協(xié)調(diào)者發(fā)送ack消息
- 4.完成事務(wù)協(xié)調(diào)者收到所有參與者返回的ack消息,完成事務(wù)
- 情況2.中斷事務(wù)
- 1.發(fā)送回滾請(qǐng)求協(xié)調(diào)者向參與者發(fā)起rollback請(qǐng)求
- 2.事務(wù)回滾參與者收到rollback請(qǐng)求后,利用undo信息執(zhí)行事務(wù)回滾操作,完成之后釋放資源
- 3.反饋事務(wù)回滾結(jié)果參與者完成事務(wù)之后,向協(xié)調(diào)者發(fā)送ack
- 4.中斷事務(wù)協(xié)調(diào)者接收到所有參與者反饋的ack,完成事務(wù)中斷
- 二階段提交的問(wèn)題
- 1.性能問(wèn)題從流程上看,在執(zhí)行過(guò)程中節(jié)點(diǎn)都處于阻塞狀態(tài)。各個(gè)操作數(shù)據(jù)庫(kù)的節(jié)點(diǎn)都占用數(shù)據(jù)庫(kù)資源,只有當(dāng)所有節(jié)點(diǎn)準(zhǔn)備完畢后,事務(wù)協(xié)調(diào)者才會(huì)通知進(jìn)行全局commit/rollback,參與者進(jìn)行本地事務(wù)commit/rollback之后才會(huì)釋放資源,對(duì)性能影響較大
- 2.單點(diǎn)故障問(wèn)題事務(wù)協(xié)調(diào)者是整個(gè)分布式事務(wù)的核心,一旦事務(wù)協(xié)調(diào)者出現(xiàn)故障,會(huì)導(dǎo)致參與者收不到commit/rollback的通知,從而導(dǎo)致參與者節(jié)點(diǎn)一直處于事務(wù)無(wú)法完成的中間狀態(tài)
- 3.數(shù)據(jù)不一致在第二階段的時(shí)候,如果發(fā)生局部網(wǎng)絡(luò)問(wèn)題,一部分事務(wù)參與者收不到commit/rollback消息,就會(huì)導(dǎo)致節(jié)點(diǎn)間數(shù)據(jù)不一致
- 4.太多保守必須 收到所有參與的正反饋才提交事務(wù)如果有任意一個(gè)事務(wù)參與者的響應(yīng)沒(méi)有收到,則整個(gè)事務(wù)失敗回滾
3pc
基于2pc出現(xiàn)的一些問(wèn)題,3pc進(jìn)行了改進(jìn),也就是三階段提交,將2pc的第二個(gè)階段進(jìn)行了一分為二,形成了CanCommit(提交詢問(wèn))、Precommit(預(yù)提交)、doCommit階段(最終提交)三個(gè)階段;其實(shí)3pc和2pc的不同點(diǎn)在于3pc增加了超時(shí)機(jī)制。
- 階段1:CanCommit(提交詢問(wèn))協(xié)調(diào)者向所有參與者發(fā)送一個(gè)請(qǐng)求,詢問(wèn)是否可以執(zhí)行事務(wù)提交操作,然后開始等待所有響應(yīng)者的響應(yīng)正常情況下,所有參與者會(huì)反饋yes,然后進(jìn)入預(yù)備狀態(tài),否則反饋No
- 2.各參與者向協(xié)調(diào)者反饋事務(wù)詢問(wèn)的響應(yīng)
- 1.事務(wù)詢問(wèn)
- 階段2:PreCommit(預(yù)提交)
- 情況1:執(zhí)行事務(wù)預(yù)提交(即所有參與者都響應(yīng)yes)
- 1.發(fā)起預(yù)提交請(qǐng)求協(xié)調(diào)者向所有參與者發(fā)出preCommit請(qǐng)求,并進(jìn)入準(zhǔn)備階段
- 2.事務(wù)預(yù)提交參與者接收到preCommit請(qǐng)求后,執(zhí)行事務(wù)操作,然后將undo和redo信息記錄到事務(wù)日志中
- 3.各參與者向協(xié)調(diào)者反饋事務(wù)執(zhí)行的響應(yīng)
- 情況2:中斷事務(wù)(任何一個(gè)參與者反饋no或者超時(shí)就會(huì)中斷事務(wù))
- 1.發(fā)送中斷請(qǐng)求
- 2.中斷事務(wù)
- 階段3:doCommit(最終提交)
- 情況1:執(zhí)行提交
- 1.發(fā)送提交請(qǐng)求
- 2.事務(wù)提交
- 3.反饋事務(wù)提交結(jié)果
- 4.完成事務(wù)
- 情況2:中斷事務(wù)
- 1.發(fā)送中斷請(qǐng)求
- 2.事務(wù)回滾
- 3.反饋事務(wù)回滾結(jié)果
- 4.中斷事務(wù)
- 3pc特點(diǎn)
- 1.降低了參與者阻塞范圍,增加了超時(shí)自動(dòng)處理的機(jī)制
- 2.能夠在出現(xiàn)單點(diǎn)故障后繼續(xù)保持一致
- 3.網(wǎng)絡(luò)分區(qū)會(huì)出現(xiàn)不一致的問(wèn)題即參與者接收到了preCommit消息后,出現(xiàn)了網(wǎng)絡(luò)分區(qū),即協(xié)調(diào)者和參與者無(wú)法進(jìn)行正常通信,這個(gè)時(shí)候該參與者依然會(huì)進(jìn)行事務(wù)的提交,就會(huì)出現(xiàn)數(shù)據(jù)不一致的情況
Paxos
Paxos算法要解決的問(wèn)題就是如何保證數(shù)據(jù)一致性,這是一種基于消息傳遞且具有高度容錯(cuò)特的一致性算法
首先要引入拜占庭問(wèn)題
拜占庭問(wèn)題:即不同軍隊(duì)的將軍之間必須制定一個(gè)統(tǒng)一的行動(dòng)計(jì)劃,但是在地理上都是分隔開來(lái)的,只能依靠通訊員進(jìn)行通信,但是通訊員可能會(huì)存在叛徒,對(duì)消息進(jìn)行篡改,從而欺騙將軍。
這種消息篡改的情況在同一個(gè)局域網(wǎng)內(nèi)幾乎不會(huì)出現(xiàn),或者簡(jiǎn)單通過(guò)校驗(yàn)算法進(jìn)行避免。但是在實(shí)際工程實(shí)踐中,可以假設(shè)不存在拜占庭問(wèn)題,基于這種假設(shè)如何保證一致性呢?這個(gè)時(shí)候又引入Paxos的故事
古希臘有一個(gè)Paxos小島,島上采用會(huì)議的形式來(lái)通過(guò)法令,議會(huì)上的議員通過(guò)信使來(lái)傳遞消息,注意信使和議員都是兼職的,有可能隨時(shí)會(huì)離開議會(huì),而且信使有可能會(huì)重復(fù)傳遞消息,也有可能一去不返。那么在這種情況下議會(huì)協(xié)議也要保證法令能夠正確選舉出來(lái),而且不會(huì)產(chǎn)生沖突。
根據(jù)這個(gè)故事也就衍生出了Paxos算法,該算法有3個(gè)角色:
1.Proposer(提議者,用來(lái)發(fā)起提案的,相當(dāng)于zk中的leader角色)
2.Acceptor(接受者,可以接受或拒絕提案,相當(dāng)于zk中的follower角色)
3.Learner(學(xué)習(xí)者,學(xué)習(xí)被選定的提案,相當(dāng)于zk中的observer角色)
注意這里講解的是Basic Paxos,基于Baisc Paxos演化出了Multi Paxos,這里不做過(guò)多講解,有興趣的同學(xué)可自行查閱
大致流程就是首先選舉出一個(gè)Leader,也就是Proposer用來(lái)發(fā)起提案,然后發(fā)送給所有的Acceptor來(lái)進(jìn)行投票,當(dāng)超過(guò)一半投通過(guò)票的時(shí)候,該提案也就通過(guò)了,那么這個(gè)時(shí)候Proposer會(huì)將該提案進(jìn)行同步所有機(jī)器進(jìn)行學(xué)習(xí)
也就是說(shuō)Paxos是基于議會(huì)制,以少數(shù)服從多數(shù)的核心思想來(lái)保證一致性的
Raft
該算法不做過(guò)多講解,想要了解,請(qǐng)查看http://thesecretlivesofdata.com/raft/網(wǎng)址
Raft算法是一個(gè)分布式共識(shí)算法,有三個(gè)角色
1.Leader
2.follower
如果follower接收不到leader的心跳時(shí),會(huì)變?yōu)閏andidate(這里會(huì)有150s~300s的等待時(shí)間),發(fā)起投票是否成為新的leader
3.candidate(候選人)
核心思想:少數(shù)服從多數(shù)!
ZAB協(xié)議
zookeeper是基于該協(xié)議(zookeeper原子廣播協(xié)議)實(shí)現(xiàn)的。這里只做簡(jiǎn)單介紹,該協(xié)議比較重要,后面會(huì)和zookeeper相關(guān)文章結(jié)合單獨(dú)進(jìn)行講解!
該協(xié)議有兩種模式:
1.崩潰恢復(fù)
2.消息廣播
它和Paxos的區(qū)別聯(lián)系在于:
1.都存在類似于Leader角色,負(fù)責(zé)協(xié)調(diào)多個(gè)Follower進(jìn)程的運(yùn)行
2.Leader進(jìn)程都會(huì)等待超過(guò)半數(shù)的Follower做出正確反饋后,才會(huì)將一個(gè)提案進(jìn)行提交
3.zab協(xié)議中,每個(gè)proposal都包含一個(gè)epoch值,用了代表當(dāng)前Leader周期;Paxos中也存在同樣的標(biāo)識(shí),名字為Ballot
4.zab協(xié)議主要用于構(gòu)建一個(gè)高可用的分布式數(shù)據(jù)主備系統(tǒng)
5.Paxos算法主要用于構(gòu)建一個(gè)分布式的一致性狀態(tài)機(jī)系統(tǒng)