您好,登錄后才能下訂單哦!
本章介紹分布式架構(gòu)的底層技術(shù)。主要說(shuō)明面試過(guò)程中可能被問(wèn)到的技術(shù)點(diǎn)。
Zookeeper
分布式
Zookeeper是一個(gè)分布式的、開(kāi)源的分布式應(yīng)用程序協(xié)調(diào)服務(wù)。它是集群的管理者,監(jiān)視著集群中各個(gè)節(jié)點(diǎn)的狀態(tài),并根據(jù)節(jié)點(diǎn)提交的反饋進(jìn)行下一步合理的操作。
對(duì)于客戶端的讀操作,可以被集群中任意一臺(tái)機(jī)器處理。如果讀請(qǐng)求在節(jié)點(diǎn)上注冊(cè)了監(jiān)聽(tīng)器,這個(gè)監(jiān)聽(tīng)器也是由所連接的機(jī)器來(lái)執(zhí)行
對(duì)于客戶端的寫(xiě)操作,這些請(qǐng)求會(huì)同時(shí)發(fā)給其他的zookeeper機(jī)器并達(dá)成一致后,請(qǐng)求才會(huì)返回成功
因此,隨著集群機(jī)器的增多,讀請(qǐng)求的吞吐會(huì)提高,而寫(xiě)請(qǐng)求的吞吐會(huì)下降
有序性是Zookeeper的另一個(gè)特點(diǎn),所有的更新操作都是全局有序的;每個(gè)更新都有唯一的時(shí)間戳,稱為zxid(Zookeeper Transaction Id);而讀請(qǐng)求只會(huì)相對(duì)于更新有序,也就是讀請(qǐng)求的返回結(jié)果中會(huì)帶有這個(gè)zookeeper的最新zxid
文件系統(tǒng) 和 通知機(jī)制
Zookeeper提供了一個(gè)多層級(jí)的節(jié)點(diǎn)命名空間(節(jié)點(diǎn)稱為znode)
與文件系統(tǒng)不同的是,它的每個(gè)節(jié)點(diǎn)都可以設(shè)置關(guān)聯(lián)數(shù)據(jù),而文件系統(tǒng)只有文件節(jié)點(diǎn)可以存放數(shù)據(jù)而目錄節(jié)點(diǎn)不行
Zookeeper為了保證高吞吐和低延遲,在內(nèi)存中維護(hù)了這個(gè)樹(shù)狀的目錄結(jié)構(gòu),所以它不能存放大量的數(shù)據(jù),每個(gè)節(jié)點(diǎn)的存放數(shù)據(jù)上限是1M
PERSISTENT
,持久化目錄節(jié)點(diǎn):客戶端與Zookeeper斷開(kāi)連接后,該節(jié)點(diǎn)依舊存在PERSISTENT_SEQUENTIAL
,持久化順序編號(hào)目錄節(jié)點(diǎn):客戶端與Zookeeper斷開(kāi)連接后,該節(jié)點(diǎn)依舊存在,只是Zookeeper給該節(jié)點(diǎn)名稱進(jìn)行順序編號(hào)EPHEMERAL
,臨時(shí)目錄節(jié)點(diǎn):客戶端與Zookeeper斷開(kāi)連接后,該節(jié)點(diǎn)被刪除EPHEMERAL_SEQUENTIAL
,臨時(shí)順序編號(hào)目錄節(jié)點(diǎn):客戶端與Zookeeper斷開(kāi)連接后,該節(jié)點(diǎn)被刪除,只是Zookeeper給該節(jié)點(diǎn)名稱進(jìn)行順序編號(hào)客戶端注冊(cè)監(jiān)聽(tīng)它關(guān)心的目錄節(jié)點(diǎn),會(huì)對(duì)該znode建立一個(gè)watcher事件,當(dāng)該znode發(fā)生變化(數(shù)據(jù)刪除、被刪除、子目錄節(jié)點(diǎn)增加刪除等)時(shí),Zookeeper會(huì)通知客戶端
? 命名服務(wù)是指通過(guò)指定的名字來(lái)獲取資源或服務(wù)的地址,即利用Zookeeper創(chuàng)建一個(gè)全局的路徑,也就是唯一的路徑,這個(gè)路徑可以作為一個(gè)名字,指向集群中的機(jī)器、提供服務(wù)的地址、一個(gè)遠(yuǎn)程對(duì)象等
? 程序分布式的部署在不同的機(jī)器上,將程序的配置信息放在zookeeper的znode下,當(dāng)配置發(fā)生變化時(shí),也就是znode發(fā)生變化時(shí),利用watcher通知各個(gè)客戶端,從而更改配置
? 所謂集群管理無(wú)非兩點(diǎn),是否有機(jī)器退出或加入、選舉master
? 第一點(diǎn),所有機(jī)器約定在父目錄下創(chuàng)建臨時(shí)目錄節(jié)點(diǎn),然后監(jiān)聽(tīng)父目錄節(jié)點(diǎn)的子節(jié)點(diǎn)變化信息;如果有機(jī)器掛了,該機(jī)器就會(huì)與Zookeeper斷開(kāi)連接,其創(chuàng)建的臨時(shí)目錄就會(huì)刪除,此時(shí)就會(huì)通知所有機(jī)器,有個(gè)兄弟機(jī)器掛了;同理,機(jī)器加入也是一樣
? 第二點(diǎn),所有機(jī)器創(chuàng)建臨時(shí)順序編號(hào)目錄節(jié)點(diǎn),每次都選取編號(hào)最小的機(jī)器作為master
? 有了Zookeeper的一致性文件系統(tǒng),鎖變得簡(jiǎn)單。鎖服務(wù)可以分為兩類:保持獨(dú)占,控制時(shí)序
? 對(duì)于保持獨(dú)占,我們將znode看作一把鎖,通過(guò)createznode的方式來(lái)實(shí)現(xiàn);所有客戶端都去創(chuàng)建/distribute_lock節(jié)點(diǎn),最終成功創(chuàng)建的那個(gè)客戶端也就獲取了這把鎖,用完刪掉/distribute_lock節(jié)點(diǎn),即可釋放鎖
? 對(duì)于控制時(shí)序,/distribute_lock已經(jīng)預(yù)先存在,所有客戶端在它下面創(chuàng)建臨時(shí)順序編號(hào)目錄節(jié)點(diǎn),和選舉master一樣,編號(hào)最小的獲得鎖,用完刪除自己的臨時(shí)順序編號(hào)目錄節(jié)點(diǎn)
在分布式鎖的場(chǎng)景下,會(huì)提前在Zookeeper中創(chuàng)建一個(gè)持久節(jié)點(diǎn)ParentLocker(名字叫什么都可以)
當(dāng)客戶端要獲取鎖時(shí),需要在ParentLocker下創(chuàng)建一個(gè)臨時(shí)順序編號(hào)節(jié)點(diǎn)Locker-n,首先,查找ParentLocker下的所有臨時(shí)子節(jié)點(diǎn)并排序,并且判斷自己創(chuàng)建的Locker-n是不是順序編號(hào)最小的,如果是,則臨時(shí)節(jié)點(diǎn)Locker-n創(chuàng)建成功,也就是獲取鎖成功;如果不是最小的,此時(shí)找到排序僅比自己靠前的節(jié)點(diǎn),向其注冊(cè)監(jiān)聽(tīng)Watcher,監(jiān)聽(tīng)其是否存在(exist),也就是該客戶端獲取鎖失敗,進(jìn)入等待;當(dāng)前一個(gè)節(jié)點(diǎn)被刪除時(shí),客戶端會(huì)收到通知,然后再次判斷自己是不是最小的,如果是則獲取鎖成功,如果不是,則再重復(fù)以上步驟
Zookeeper的核心是原子廣播,保證了各個(gè)Server之間的同步;實(shí)現(xiàn)這個(gè)機(jī)制的協(xié)議叫做Zab協(xié)議。Zab協(xié)議有兩種模式,恢復(fù)模式(選主)和廣播模式(同步)。當(dāng)服務(wù)啟動(dòng)或者領(lǐng)導(dǎo)者崩潰后,Zab進(jìn)入恢復(fù)模式;當(dāng)選舉了新的領(lǐng)導(dǎo)者,并且大多數(shù)Server和leader的狀態(tài)同步完成之后,恢復(fù)模式就結(jié)束了。狀態(tài)同步保證了leader和server之間有相同的系統(tǒng)狀態(tài)
采用遞增的事務(wù)ID:zxid來(lái)標(biāo)識(shí),所有的proposal(提議)都會(huì)加上zxid。zxid是64位的數(shù)字,高32位是epoch,用來(lái)標(biāo)識(shí)leader是否發(fā)生變化,如果是新選舉的leader,則epoch會(huì)遞增;低32位是遞增計(jì)數(shù)的。當(dāng)有新的proposal提出時(shí),首先向其他server發(fā)出事務(wù)執(zhí)行請(qǐng)求,如果有超過(guò)半數(shù)的機(jī)器都能執(zhí)行且能夠執(zhí)行成功,然后才會(huì)開(kāi)始執(zhí)行
當(dāng)leader崩潰或失去大多數(shù)follower,這時(shí)會(huì)進(jìn)入恢復(fù)模式。選舉算法有兩種:一種是基于basic paxos實(shí)現(xiàn)的,一種是基于fast paxos實(shí)現(xiàn)的,默認(rèn)是fast paxos。
basic paxos算法
a) 每個(gè)Server上的選舉線程由當(dāng)前Server發(fā)起選舉的線程擔(dān)任,主要職責(zé)是對(duì)各個(gè)投票結(jié)果進(jìn)行統(tǒng)計(jì),選舉 出新的leader
b) 選舉線程向所有Server發(fā)起一次詢問(wèn)(包括自己)
c) 選舉線程收到回復(fù)后,驗(yàn)證是否是自己發(fā)出的詢問(wèn)(驗(yàn)證zxid是否一致),然后獲取對(duì)方的myid,將之存儲(chǔ)到當(dāng)前詢問(wèn)的對(duì)象列表中,最后獲取對(duì)方提議的leader相關(guān)信息(myid,zxid),存儲(chǔ)到當(dāng)次選舉的投票記錄中
d) 收到所有的Server回復(fù)后,計(jì)算出zxid最大的Server,然后統(tǒng)計(jì)它的票數(shù),如果它獲得了n/2+1的Server票數(shù),則設(shè)置為新的leader。否則,重新再次選舉
通過(guò)該選舉流程可以得出,要使leader獲得多數(shù)Server的支持,Server的總數(shù)必須是奇數(shù)2n+1,且存活的Server數(shù)目不得少于n+1
fast paxos算法
在選舉時(shí),首先向所有Server提議自己要成為leader,當(dāng)其他Server收到提議后,會(huì)進(jìn)行PK(zxid大myid大的獲勝),并回復(fù)同意還是拒絕,重復(fù)這個(gè)流程,就會(huì)選擇出一個(gè)新的leader
選完leader后,進(jìn)入同步流程
zk的負(fù)載均衡可以調(diào)控,nginx只能調(diào)權(quán)重,其他的都要自己寫(xiě)插件,但是nginx的吞吐量比zk大得多
一個(gè)watch事件是一個(gè)一次性的觸發(fā)器,當(dāng)被設(shè)置了watch的數(shù)據(jù)發(fā)生了變化時(shí),服務(wù)器會(huì)將這個(gè)變化發(fā)送給設(shè)置了watch的客戶端
public Zookeeper(String connStr, int sessionTimeout, Watcher watcher)
),服務(wù)器端只是存儲(chǔ)了是否設(shè)置了watch的布爾變量免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。