這期內(nèi)容當(dāng)中小編將會給大家?guī)碛嘘P(guān)ZooKeeper的問題都有哪些,文章內(nèi)容豐富且以專業(yè)的角度為大家分析和敘述,閱讀完這篇文章希望大家可以有所收獲。
創(chuàng)新互聯(lián)成立與2013年,是專業(yè)互聯(lián)網(wǎng)技術(shù)服務(wù)公司,擁有項目成都網(wǎng)站制作、做網(wǎng)站、外貿(mào)營銷網(wǎng)站建設(shè)網(wǎng)站策劃,項目實施與項目整合能力。我們以讓每一個夢想脫穎而出為使命,1280元淮南做網(wǎng)站,已為上家服務(wù),為淮南各地企業(yè)和個人服務(wù),聯(lián)系電話:13518219792
1. 面試官:工作中使用過Zookeeper嘛?你知道它是什么,有什么用途呢?
「小菜雞的我:」
有使用過的,使用ZooKeeper作為「dubbo的注冊中心」,使用ZooKeeper實現(xiàn)「分布式鎖」。
ZooKeeper,它是一個開放源碼的「分布式協(xié)調(diào)服務(wù)」,它是一個集群的管理者,它將簡單易用的接口提供給用戶。
可以基于Zookeeper 實現(xiàn)諸如數(shù)據(jù)發(fā)布/訂閱、負(fù)載均衡、命名服務(wù)、分布式協(xié)調(diào)/通知、集群管理、Master 選舉、分布式鎖和分布式隊列「等功能」。
Zookeeper的「用途」:命名服務(wù)、配置管理、集群管理、分布式鎖、隊列管理
用途跟功能不是一個意思咩?給我一個眼神,讓我自己體會
2. 面試官:說下什么是命名服務(wù),什么是配置管理,又什么是集群管理吧
「小菜雞的我(幸好我刷過面試題),無所畏懼」
「命名服務(wù)就是」:
命名服務(wù)是指通過「指定的名字」來獲取資源或者服務(wù)地址。Zookeeper可以創(chuàng)建一個「全局唯一的路徑」,這個路徑就可以作為一個名字。被命名的實體可以是「集群中的機器,服務(wù)的地址,或者是遠(yuǎn)程的對象」等。一些分布式服務(wù)框架(RPC、RMI)中的服務(wù)地址列表,通過使用命名服務(wù),客戶端應(yīng)用能夠根據(jù)特定的名字來獲取資源的實體、服務(wù)地址和提供者信息等。
「配置管理」 :
實際項目開發(fā)中,我們經(jīng)常使用.properties或者xml需要配置很多信息,如數(shù)據(jù)庫連接信息、fps地址端口等等。因為你的程序一般是分布式部署在不同的機器上(如果你是單機應(yīng)用當(dāng)我沒說),如果把程序的這些配置信息「保存在zk的znode節(jié)點」下,當(dāng)你要修改配置,即znode會發(fā)生變化時,可以通過改變zk中某個目錄節(jié)點的內(nèi)容,利用「watcher通知給各個客戶端」,從而更改配置。
「集群管理」
集群管理包括集群監(jiān)控和集群控制,其實就是監(jiān)控集群機器狀態(tài),剔除機器和加入機器。zookeeper可以方便集群機器的管理,它可以實時監(jiān)控znode節(jié)點的變化,一旦發(fā)現(xiàn)有機器掛了,該機器就會與zk斷開連接,對用的臨時目錄節(jié)點會被刪除,其他所有機器都收到通知。新機器加入也是類似醬紫,所有機器收到通知:有新兄弟目錄加入啦。
3. 面試官:你提到了znode節(jié)點,那你知道znode有幾種類型呢?zookeeper的數(shù)據(jù)模型是怎樣的呢?
「小菜雞的我(我先想想):」
zookeeper的數(shù)據(jù)模型
ZooKeeper的視圖數(shù)據(jù)結(jié)構(gòu),很像Unix文件系統(tǒng),也是樹狀的,這樣可以確定每個路徑都是唯一的。zookeeper的節(jié)點統(tǒng)一叫做「znode」,它是可以通過「路徑來標(biāo)識」,結(jié)構(gòu)圖如下:
znode的4種類型
根據(jù)節(jié)點的生命周期,znode可以分為4種類型,分別是持久節(jié)點(PERSISTENT)、持久順序節(jié)點(PERSISTENT_SEQUENTIAL)、臨時節(jié)點(EPHEMERAL)、臨時順序節(jié)點(EPHEMERAL_SEQUENTIAL)
持久節(jié)點(PERSISTENT)
這類節(jié)點被創(chuàng)建后,就會一直存在于Zk服務(wù)器上。直到手動刪除。
持久順序節(jié)點(PERSISTENT_SEQUENTIAL)
它的基本特性同持久節(jié)點,不同在于增加了順序性。父節(jié)點會維護一個自增整性數(shù)字,用于子節(jié)點的創(chuàng)建的先后順序。
臨時節(jié)點(EPHEMERAL)
臨時節(jié)點的生命周期與客戶端的會話綁定,一旦客戶端會話失效(非TCP連接斷開),那么這個節(jié)點就會被自動清理掉。zk規(guī)定臨時節(jié)點只能作為葉子節(jié)點。
臨時順序節(jié)點(EPHEMERAL_SEQUENTIAL)
基本特性同臨時節(jié)點,添加了順序的特性。
4、面試官:你知道znode節(jié)點里面存儲的是什么嗎?每個節(jié)點的數(shù)據(jù)最大不能超過多少呢?
「小菜雞的我:」
znode節(jié)點里面存儲的是什么?
Znode數(shù)據(jù)節(jié)點的代碼如下
public class DataNode implements Record { byte data[]; Long acl; public StatPersisted stat; private Setchildren = null; }
哈哈,Znode包含了「存儲數(shù)據(jù)、訪問權(quán)限、子節(jié)點引用、節(jié)點狀態(tài)信息」,如圖:
「data:」 znode存儲的業(yè)務(wù)數(shù)據(jù)信息
「ACL:」 記錄客戶端對znode節(jié)點的訪問權(quán)限,如IP等。
「child:」 當(dāng)前節(jié)點的子節(jié)點引用
「stat:」 包含Znode節(jié)點的狀態(tài)信息,比如「事務(wù)id、版本號、時間戳」等等。
每個節(jié)點的數(shù)據(jù)最大不能超過多少呢
為了保證高吞吐和低延遲,以及數(shù)據(jù)的一致性,znode只適合存儲非常小的數(shù)據(jù),不能超過1M,最好都小于1K。
5、面試官:你知道znode節(jié)點上的監(jiān)聽機制嘛?講下Zookeeper watch機制吧。
「小菜雞的我:」
Watcher機制
監(jiān)聽機制的工作原理
Watcher特性總結(jié)
Watcher監(jiān)聽機制
Zookeeper 允許客戶端向服務(wù)端的某個Znode注冊一個Watcher監(jiān)聽,當(dāng)服務(wù)端的一些指定事件觸發(fā)了這個Watcher,服務(wù)端會向指定客戶端發(fā)送一個事件通知來實現(xiàn)分布式的通知功能,然后客戶端根據(jù) Watcher通知狀態(tài)和事件類型做出業(yè)務(wù)上的改變。
可以把Watcher理解成客戶端注冊在某個Znode上的觸發(fā)器,當(dāng)這個Znode節(jié)點發(fā)生變化時(增刪改查),就會觸發(fā)Znode對應(yīng)的注冊事件,注冊的客戶端就會收到異步通知,然后做出業(yè)務(wù)的改變。
Watcher監(jiān)聽機制的工作原理
ZooKeeper的Watcher機制主要包括客戶端線程、客戶端 WatcherManager、Zookeeper服務(wù)器三部分。
客戶端向ZooKeeper服務(wù)器注冊Watcher的同時,會將Watcher對象存儲在客戶端的WatchManager中。
當(dāng)zookeeper服務(wù)器觸發(fā)watcher事件后,會向客戶端發(fā)送通知, 客戶端線程從 WatcherManager 中取出對應(yīng)的 Watcher 對象來執(zhí)行回調(diào)邏輯。
Watcher特性總結(jié)
「一次性:」 一個Watch事件是一個一次性的觸發(fā)器。一次性觸發(fā),客戶端只會收到一次這樣的信息。
「異步的:」 Zookeeper服務(wù)器發(fā)送watcher的通知事件到客戶端是異步的,不能期望能夠監(jiān)控到節(jié)點每次的變化,Zookeeper只能保證最終的一致性,而無法保證強一致性。
「輕量級:」 Watcher 通知非常簡單,它只是通知發(fā)生了事件,而不會傳遞事件對象內(nèi)容。
「客戶端串行:」 執(zhí)行客戶端 Watcher 回調(diào)的過程是一個串行同步的過程。
注冊 watcher用getData、exists、getChildren方法
觸發(fā) watcher用create、delete、setData方法
6、面試官:你對Zookeeper的數(shù)據(jù)結(jié)構(gòu)都有一定了解,那你講下Zookeeper的特性吧
「小菜雞的我:(我背過書,啊哈哈)」
Zookeeper 保證了如下分布式一致性特性:
「順序一致性」:從同一客戶端發(fā)起的事務(wù)請求,最終將會嚴(yán)格地按照順序被應(yīng)用到 ZooKeeper 中去。
「原子性」:所有事務(wù)請求的處理結(jié)果在整個集群中所有機器上的應(yīng)用情況是一致的,也就是說,要么整個集群中所有的機器都成功應(yīng)用了某一個事務(wù),要么都沒有應(yīng)用。
「單一視圖」:無論客戶端連到哪一個 ZooKeeper 服務(wù)器上,其看到的服務(wù)端數(shù)據(jù)模型都是一致的。
「可靠性:」 一旦服務(wù)端成功地應(yīng)用了一個事務(wù),并完成對客戶端的響應(yīng),那么該事務(wù)所引起的服務(wù)端狀態(tài)變更將會被一直保留下來。
「實時性(最終一致性):」 Zookeeper 僅僅能保證在一定的時間段內(nèi),客戶端最終一定能夠從服務(wù)端上讀取到最新的數(shù)據(jù)狀態(tài)。
7、面試官:你剛提到順序一致性,那zookeeper是如何保證事務(wù)的順序一致性的呢?
「小菜雞的我:(完蛋了這題不會)」
這道題可以看下這篇文章(本題答案來自該文章):聊一聊ZooKeeper的順序一致性[1] https://time.geekbang.org/column/article/239261
需要了解事務(wù)ID,即zxid。ZooKeeper的在選舉時通過比較各結(jié)點的zxid和機器ID選出新的主結(jié)點的。zxid由Leader節(jié)點生成,有新寫入事件時,Leader生成新zxid并隨提案一起廣播,每個結(jié)點本地都保存了當(dāng)前最近一次事務(wù)的zxid,zxid是遞增的,所以誰的zxid越大,就表示誰的數(shù)據(jù)是最新的。
ZXID的生成規(guī)則如下:
ZXID有兩部分組成:
任期:完成本次選舉后,直到下次選舉前,由同一Leader負(fù)責(zé)協(xié)調(diào)寫入;
事務(wù)計數(shù)器:單調(diào)遞增,每生效一次寫入,計數(shù)器加一。
ZXID的低32位是計數(shù)器,所以同一任期內(nèi),ZXID是連續(xù)的,每個結(jié)點又都保存著自身最新生效的ZXID,通過對比新提案的ZXID與自身最新ZXID是否相差“1”,來保證事務(wù)嚴(yán)格按照順序生效的。
8、面試官:你提到了Leader,你知道Zookeeper的服務(wù)器有幾種角色嘛?Zookeeper下Server工作狀態(tài)又有幾種呢?
「小菜雞的我:」
Zookeeper 服務(wù)器角色
Zookeeper集群中,有Leader、Follower和Observer三種角色
「Leader」
Leader服務(wù)器是整個ZooKeeper集群工作機制中的核心,其主要工作:
事務(wù)請求的唯一調(diào)度和處理者,保證集群事務(wù)處理的順序性
集群內(nèi)部各服務(wù)的調(diào)度者
「Follower」
Follower服務(wù)器是ZooKeeper集群狀態(tài)的跟隨者,其主要工作:
處理客戶端非事務(wù)請求,轉(zhuǎn)發(fā)事務(wù)請求給Leader服務(wù)器
參與事務(wù)請求Proposal的投票
參與Leader選舉投票
「Observer」
Observer是3.3.0 版本開始引入的一個服務(wù)器角色,它充當(dāng)一個觀察者角色——觀察ZooKeeper集群的最新狀態(tài)變化并將這些狀態(tài)變更同步過來。其工作:
處理客戶端的非事務(wù)請求,轉(zhuǎn)發(fā)事務(wù)請求給 Leader 服務(wù)器
不參與任何形式的投票
Zookeeper下Server工作狀態(tài)
服務(wù)器具有四種狀態(tài),分別是 LOOKING、FOLLOWING、LEADING、OBSERVING。
1.LOOKING:尋找Leader狀態(tài)。當(dāng)服務(wù)器處于該狀態(tài)時,它會認(rèn)為當(dāng)前集群中沒有 Leader,因此需要進(jìn)入 Leader 選舉狀態(tài)。
2.FOLLOWING:跟隨者狀態(tài)。表明當(dāng)前服務(wù)器角色是Follower。
3.LEADING:領(lǐng)導(dǎo)者狀態(tài)。表明當(dāng)前服務(wù)器角色是Leader。
4.OBSERVING:觀察者狀態(tài)。表明當(dāng)前服務(wù)器角色是Observer。
9、面試官:你說到服務(wù)器角色是基于ZooKeeper集群的,那你畫一下ZooKeeper集群部署圖吧?ZooKeeper是如何保證主從節(jié)點數(shù)據(jù)一致性的呢?
「小菜雞的我:」
ZooKeeper集群部署圖
ZooKeeper集群是一主多從的結(jié)構(gòu):
如果是寫入數(shù)據(jù),先寫入主服務(wù)器(主節(jié)點),再通知從服務(wù)器。
如果是讀取數(shù)據(jù),既讀主服務(wù)器的,也可以讀從服務(wù)器的。
ZooKeeper如何保證主從節(jié)點數(shù)據(jù)一致性
我們知道集群是主從部署結(jié)構(gòu),要保證主從節(jié)點一致性問題,無非就是兩個主要問題:
「主服務(wù)器掛了,或者重啟了」
「主從服務(wù)器之間同步數(shù)據(jù)」~
Zookeeper是采用ZAB協(xié)議(Zookeeper Atomic Broadcast,Zookeeper原子廣播協(xié)議)來保證主從節(jié)點數(shù)據(jù)一致性的,ZAB協(xié)議支持「崩潰恢復(fù)和消息廣播」兩種模式,很好解決了這兩個問題:
崩潰恢復(fù):Leader掛了,進(jìn)入該模式,選一個新的leader出來
消息廣播:把更新的數(shù)據(jù),從Leader同步到所有Follower
Leader服務(wù)器掛了,所有集群中的服務(wù)器進(jìn)入LOOKING狀態(tài),首先,它們會選舉產(chǎn)生新的Leader服務(wù)器;接著,新的Leader服務(wù)器與集群中Follower服務(wù)進(jìn)行數(shù)據(jù)同步,當(dāng)集群中超過半數(shù)機器與該 Leader服務(wù)器完成數(shù)據(jù)同步之后,退出恢復(fù)模式進(jìn)入消息廣播模式。Leader 服務(wù)器開始接收客戶端的事務(wù)請求生成事務(wù)Proposal進(jìn)行事務(wù)請求處理。
10、面試官:Leader掛了,進(jìn)入崩潰恢復(fù),是如何選舉Leader的呢?你講一下ZooKeeper選舉機制吧
「小菜雞的我:」
服務(wù)器啟動或者服務(wù)器運行期間(Leader掛了),都會進(jìn)入Leader選舉,我們來看一下~假設(shè)現(xiàn)在ZooKeeper集群有五臺服務(wù)器,它們myid分別是服務(wù)器1、2、3、4、5,如圖:
服務(wù)器啟動的Leader選舉
zookeeper集群初始化階段,服務(wù)器(myid=1-5)「依次」啟動,開始zookeeper選舉Leader~
服務(wù)器1(myid=1)啟動,當(dāng)前只有一臺服務(wù)器,無法完成Leader選舉
服務(wù)器2(myid=2)啟動,此時兩臺服務(wù)器能夠相互通訊,開始進(jìn)入Leader選舉階段
1.每個服務(wù)器發(fā)出一個投票
服務(wù)器1 和 服務(wù)器2都將自己作為Leader服務(wù)器進(jìn)行投票,投票的基本元素包括:服務(wù)器的myid和ZXID,我們以(myid,ZXID)形式表示。初始階段,服務(wù)器1和服務(wù)器2都會投給自己,即服務(wù)器1的投票為(1,0),服務(wù)器2的投票為(2,0),然后各自將這個投票發(fā)給集群中的其他所有機器。
2.接受來自各個服務(wù)器的投票
每個服務(wù)器都會接受來自其他服務(wù)器的投票。同時,服務(wù)器會校驗投票的有效性,是否本輪投票、是否來自LOOKING狀態(tài)的服務(wù)器。
3.處理投票
收到其他服務(wù)器的投票,會將別人的投票跟自己的投票PK,PK規(guī)則如下:
優(yōu)先檢查ZXID。ZXID比較大的服務(wù)器優(yōu)先作為leader。
如果ZXID相同的話,就比較myid,myid比較大的服務(wù)器作為leader。服務(wù)器1的投票是(1,0),它收到投票是(2,0),兩者zxid都是0,因為收到的myid=2,大于自己的myid=1,所以它更新自己的投票為(2,0),然后重新將投票發(fā)出去。對于服務(wù)器2呢,即不再需要更新自己的投票,把上一次的投票信息發(fā)出即可。
4.統(tǒng)計投票
每次投票后,服務(wù)器會統(tǒng)計所有投票,判斷是否有過半的機器接受到相同的投票信息。服務(wù)器2收到兩票,少于3(n/2+1,n為總服務(wù)器5),所以繼續(xù)保持LOOKING狀態(tài)
服務(wù)器3(myid=3)啟動,繼續(xù)進(jìn)入Leader選舉階段
跟前面流程一致,服務(wù)器1和2先投自己一票,因為服務(wù)器3的myid最大,所以大家把票改投給它。此時,服務(wù)器為3票(大于等于n/2+1),所以服務(wù)器3當(dāng)選為Leader。服務(wù)器1,2更改狀態(tài)為FOLLOWING,服務(wù)器3更改狀態(tài)為LEADING;
服務(wù)器4啟動,發(fā)起一次選舉。
此時服務(wù)器1,2,3已經(jīng)不是LOOKING狀態(tài),不會更改選票信息。選票信息結(jié)果:服務(wù)器3為3票,服務(wù)器4為1票。服務(wù)器4并更改狀態(tài)為FOLLOWING;
服務(wù)器5啟動,發(fā)起一次選舉。
同理,服務(wù)器也是把票投給服務(wù)器3,服務(wù)器5并更改狀態(tài)為FOLLOWING;
投票結(jié)束,服務(wù)器3當(dāng)選為Leader
服務(wù)器運行期間的Leader選舉
zookeeper集群的五臺服務(wù)器(myid=1-5)正在運行中,突然某個瞬間,Leader服務(wù)器3掛了,這時候便開始Leader選舉~
1.變更狀態(tài)
Leader 服務(wù)器掛了之后,余下的非Observer服務(wù)器都會把自己的服務(wù)器狀態(tài)更改為LOOKING,然后開始進(jìn)入Leader選舉流程。
2.每個服務(wù)器發(fā)起投票
每個服務(wù)器都把票投給自己,因為是運行期間,所以每臺服務(wù)器的ZXID可能不相同。假設(shè)服務(wù)1,2,4,5的zxid分別為333,666,999,888,則分別產(chǎn)生投票(1,333),(2,666),(4,999)和(5,888),然后各自將這個投票發(fā)給集群中的其他所有機器。
3.接受來自各個服務(wù)器的投票
4.處理投票
投票規(guī)則是跟Zookeeper集群啟動期間一致的,優(yōu)先檢查ZXID,大的優(yōu)先作為Leader,所以顯然服務(wù)器zxid=999具有優(yōu)先權(quán)。
5.統(tǒng)計投票
6.改變服務(wù)器狀態(tài)
11、面試官:你前面提到在項目中使用過Zookeeper的分布式鎖,講一下zk分布式鎖的實現(xiàn)原理吧?
「小菜雞的我:」
Zookeeper就是使用臨時順序節(jié)點特性實現(xiàn)分布式鎖的。
獲取鎖過程 (創(chuàng)建臨時節(jié)點,檢查序號最小)
釋放鎖 (刪除臨時節(jié)點,監(jiān)聽通知)
獲取鎖過程
當(dāng)?shù)谝粋€客戶端請求過來時,Zookeeper客戶端會創(chuàng)建一個持久節(jié)點/locks。如果它(Client1)想獲得鎖,需要在locks節(jié)點下創(chuàng)建一個順序節(jié)點lock1.如圖
接著,客戶端Client1會查找locks下面的所有臨時順序子節(jié)點,判斷自己的節(jié)點lock1是不是排序最小的那一個,如果是,則成功獲得鎖。
這時候如果又來一個客戶端client2前來嘗試獲得鎖,它會在locks下再創(chuàng)建一個臨時節(jié)點lock2
客戶端client2一樣也會查找locks下面的所有臨時順序子節(jié)點,判斷自己的節(jié)點lock2是不是最小的,此時,發(fā)現(xiàn)lock1才是最小的,于是獲取鎖失敗。獲取鎖失敗,它是不會甘心的,client2向它排序靠前的節(jié)點lock1注冊Watcher事件,用來監(jiān)聽lock1是否存在,也就是說client2搶鎖失敗進(jìn)入等待狀態(tài)。
此時,如果再來一個客戶端Client3來嘗試獲取鎖,它會在locks下再創(chuàng)建一個臨時節(jié)點lock3
同樣的,client3一樣也會查找locks下面的所有臨時順序子節(jié)點,判斷自己的節(jié)點lock3是不是最小的,發(fā)現(xiàn)自己不是最小的,就獲取鎖失敗。它也是不會甘心的,它會向在它前面的節(jié)點lock2注冊Watcher事件,以監(jiān)聽lock2節(jié)點是否存在。
釋放鎖
我們再來看看釋放鎖的流程,zookeeper的「客戶端業(yè)務(wù)完成或者故障」,都會刪除臨時節(jié)點,釋放鎖。如果是任務(wù)完成,Client1會顯式調(diào)用刪除lock1的指令
如果是客戶端故障了,根據(jù)臨時節(jié)點得特性,lock1是會自動刪除的
lock1節(jié)點被刪除后,Client2可開心了,因為它一直監(jiān)聽著lock1。lock1節(jié)點刪除,Client2立刻收到通知,也會查找locks下面的所有臨時順序子節(jié)點,發(fā)下lock2是最小,就獲得鎖。
同理,Client2獲得鎖之后,Client3也對它虎視眈眈,啊哈哈~
12. 面試官:好的,最后一道題,你說說dubbo和Zookeeper的關(guān)系吧,為什么選擇Zookeeper作為注冊中心?
小菜雞的我(答了這么多道題,不會還不給我過吧?):
dubbo的注冊中心可以選Zookeeper,memcached,redis等。為什么選擇Zookeeper,因為它的功能特性咯~
命名服務(wù),服務(wù)提供者向Zookeeper指定節(jié)點寫入url,完成服務(wù)發(fā)布。
負(fù)載均衡,注冊中心的承載能力有限,而Zookeeper集群配合web應(yīng)用很容易達(dá)到負(fù)載均衡。
zk支持監(jiān)聽事件,特別適合發(fā)布/訂閱的場景,dubbo的生產(chǎn)者和消費者就類似這場景。
數(shù)據(jù)模型簡單,數(shù)據(jù)存在內(nèi)存,可謂高性能
Zookeeper其他特點都可以搬出來講一下~
上述就是小編為大家分享的ZooKeeper的問題都有哪些了,如果剛好有類似的疑惑,不妨參照上述分析進(jìn)行理解。如果想知道更多相關(guān)知識,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道。