Paxos廓八,它是一個(gè)基于消息傳遞的一致性算法鳞贷,Leslie Lamport在1990年提出,近幾年被廣泛應(yīng)用于分布式計(jì)算中伦籍,Google的Chubby,Apache的Zookeeper都是基于它的理論來實(shí)現(xiàn)的凤价,Paxos還被認(rèn)為是到目前為止唯一的分布式一致性算法鸽斟,其它的算法都是Paxos的改進(jìn)或簡(jiǎn)化。有個(gè)問題要提一下利诺,Paxos有一個(gè)前提:沒有拜占庭將軍問題富蓄。就是說Paxos只有在一個(gè)可信的計(jì)算環(huán)境中才能成立,這個(gè)環(huán)境是不會(huì)被入侵所破壞的慢逾。
關(guān)于Paxos的具體描述可以在Wiki中找到:http://zh.wikipedia.org/zh-cn/Paxos算法立倍。網(wǎng)上關(guān)于Paxos分析的文章也很多。這里希望用最簡(jiǎn)單的方式加以描述并建立起Paxos和ZK Server的對(duì)應(yīng)關(guān)系侣滩。
Paxos描述了這樣一個(gè)場(chǎng)景口注,有一個(gè)叫做Paxos的小島(Island)上面住了一批居民,島上面所有的事情由一些特殊的人決定君珠,他們叫做議員(Senator)寝志。議員的總數(shù)(Senator Count)是確定的,不能更改策添。島上每次環(huán)境事務(wù)的變更都需要通過一個(gè)提議(Proposal)材部,每個(gè)提議都有一個(gè)編號(hào)(PID),這個(gè)編號(hào)是一直增長(zhǎng)的唯竹,不能倒退乐导。每個(gè)提議都需要超過半數(shù)((Senator Count)/2 +1)的議員同意才能生效。每個(gè)議員只會(huì)同意大于當(dāng)前編號(hào)的提議浸颓,包括已生效的和未生效的物臂。如果議員收到小于等于當(dāng)前編號(hào)的提議,他會(huì)拒絕产上,并告知對(duì)方:你的提議已經(jīng)有人提過了棵磷。這里的當(dāng)前編號(hào)是每個(gè)議員在自己記事本上面記錄的編號(hào),他不斷更新這個(gè)編號(hào)晋涣。整個(gè)議會(huì)不能保證所有議員記事本上的編號(hào)總是相同的∫敲剑現(xiàn)在議會(huì)有一個(gè)目標(biāo):保證所有的議員對(duì)于提議都能達(dá)成一致的看法。
好姻僧,現(xiàn)在議會(huì)開始運(yùn)作规丽,所有議員一開始記事本上面記錄的編號(hào)都是0。有一個(gè)議員發(fā)了一個(gè)提議:將電費(fèi)設(shè)定為1元/度撇贺。他首先看了一下記事本赌莺,嗯,當(dāng)前提議編號(hào)是0松嘶,那么我的這個(gè)提議的編號(hào)就是1艘狭,于是他給所有議員發(fā)消息:1號(hào)提議,設(shè)定電費(fèi)1元/度翠订。其他議員收到消息以后查了一下記事本巢音,哦,當(dāng)前提議編號(hào)是0尽超,這個(gè)提議可接受官撼,于是他記錄下這個(gè)提議并回復(fù):我接受你的1號(hào)提議,同時(shí)他在記事本上記錄:當(dāng)前提議編號(hào)為1似谁。發(fā)起提議的議員收到了超過半數(shù)的回復(fù)傲绣,立即給所有人發(fā)通知:1號(hào)提議生效!收到的議員會(huì)修改他的記事本巩踏,將1好提議由記錄改成正式的法令秃诵,當(dāng)有人問他電費(fèi)為多少時(shí),他會(huì)查看法令并告訴對(duì)方:1元/度塞琼。
現(xiàn)在看沖突的解決:假設(shè)總共有三個(gè)議員S1-S3菠净,S1和S2同時(shí)發(fā)起了一個(gè)提議:1號(hào)提議,設(shè)定電費(fèi)彪杉。S1想設(shè)為1元/度, S2想設(shè)為2元/度毅往。結(jié)果S3先收到了S1的提議,于是他做了和前面同樣的操作在讶。緊接著他又收到了S2的提議煞抬,結(jié)果他一查記事本,咦构哺,這個(gè)提議的編號(hào)小于等于我的當(dāng)前編號(hào)1革答,于是他拒絕了這個(gè)提議:對(duì)不起,這個(gè)提議先前提過了曙强。于是S2的提議被拒絕残拐,S1正式發(fā)布了提議: 1號(hào)提議生效。S2向S1或者S3打聽并更新了1號(hào)法令的內(nèi)容碟嘴,然后他可以選擇繼續(xù)發(fā)起2號(hào)提議溪食。
好,我覺得Paxos的精華就這么多內(nèi)容∧壬龋現(xiàn)在讓我們來對(duì)號(hào)入座错沃,看看在ZK Server里面Paxos是如何得以貫徹實(shí)施的栅组。
小島(Island)——ZK Server Cluster
議員(Senator)——ZK Server
提議(Proposal)——ZNode Change(Create/Delete/SetData…)
提議編號(hào)(PID)——Zxid(ZooKeeper Transaction Id)
正式法令——所有ZNode及其數(shù)據(jù)
貌似關(guān)鍵的概念都能一一對(duì)應(yīng)上,但是等一下枢析,Paxos島上的議員應(yīng)該是人人平等的吧玉掸,而ZK Server好像有一個(gè)Leader的概念。沒錯(cuò)醒叁,其實(shí)Leader的概念也應(yīng)該屬于Paxos范疇的司浪。如果議員人人平等,在某種情況下會(huì)由于提議的沖突而產(chǎn)生一個(gè)“活鎖”(所謂活鎖我的理解是大家都沒有死把沼,都在動(dòng)啊易,但是一直解決不了沖突問題)。Paxos的作者Lamport在他的文章”The Part-Time Parliament“中闡述了這個(gè)問題并給出了解決方案——在所有議員中設(shè)立一個(gè)總統(tǒng)饮睬,只有總統(tǒng)有權(quán)發(fā)出提議租谈,如果議員有自己的提議,必須發(fā)給總統(tǒng)并由總統(tǒng)來提出续捂。好垦垂,我們又多了一個(gè)角色:總統(tǒng)。
總統(tǒng)——ZK Server Leader
又一個(gè)問題產(chǎn)生了牙瓢,總統(tǒng)怎么選出來的劫拗?
現(xiàn)在我們假設(shè)總統(tǒng)已經(jīng)選好了,下面看看ZK Server是怎么實(shí)施的矾克。
情況一:
屁民甲(Client)到某個(gè)議員(ZK Server)那里詢問(Get)某條法令的情況(ZNode的數(shù)據(jù))页慷,議員毫不猶豫的拿出他的記事本(local storage),查閱法令并告訴他結(jié)果胁附,同時(shí)聲明:我的數(shù)據(jù)不一定是最新的酒繁。你想要最新的數(shù)據(jù)?沒問題控妻,等著州袒,等我找總統(tǒng)Sync一下再告訴你。
情況二:
屁民乙(Client)到某個(gè)議員(ZK Server)那里要求政府歸還欠他的一萬(wàn)元錢弓候,議員讓他在辦公室等著郎哭,自己將問題反映給了總統(tǒng),總統(tǒng)詢問所有議員的意見菇存,多數(shù)議員表示欠屁民的錢一定要還夸研,于是總統(tǒng)發(fā)表聲明,從國(guó)庫(kù)中拿出一萬(wàn)元還債依鸥,國(guó)庫(kù)總資產(chǎn)由100萬(wàn)變成99萬(wàn)亥至。屁民乙拿到錢回去了(Client函數(shù)返回)。
情況三:
總統(tǒng)突然掛了,議員接二連三的發(fā)現(xiàn)聯(lián)系不上總統(tǒng)姐扮,于是各自發(fā)表聲明絮供,推選新的總統(tǒng),總統(tǒng)大選期間政府停業(yè)茶敏,拒絕屁民的請(qǐng)求杯缺。