Java面試題2.0--zookeeper

 

歡迎關注《Java面試題2.0》合集發佈頁,持續更新中!

 

 
Zookeeper是什麼框架
分佈式開源框架,提供分佈式協調服務,解決了分佈式一致性問題。原本是Hadoop、HBase的一個重要組件。
 
應用場景
數據發佈與訂閱(配置中心)
 
發佈與訂閱模型,即所謂的配置中心,顧名思義就是發佈者將數據發佈到ZK節點上,供訂閱者動態獲取數據,實現配置信息的集中式管理和動態更新。例如全局的配置信息,服務式服務框架的服務地址列表等就非常適合使用。
 
 
負載均衡
 
消費負載均衡: 在消費過程中,一個消費者會消費一個或多個分區中的消息,但是一個分區只會由一個消費者來消費。MetaQ的消費策略是:
1. 每個分區針對同一個group只掛載一個消費者。
2. 如果同一個group的消費者數目大於分區數目,則多出來的消費者將不參與消費。
3. 如果同一個group的消費者數目小於分區數目,則有部分消費者需要額外承擔消費任務。
在某個消費者故障或者重啓等情況下,其他消費者會感知到這一變化(通過 zookeeper watch消費者列表),然後重新進行負載均衡,保證所有的分區都有消費者進行消費。
 
命名服務(Naming Service)
 
命名服務也是分佈式系統中比較常見的一類場景。在分佈式系統中,通過使用命名服務,客戶端應用能夠根據指定名字來獲取資源或服務的地址,提供者等信息。被命名的實體通常可以是集羣中的機器,提供的服務地址,遠程對象等等——這些我們都可以統稱他們爲名字(Name)。其中較爲常見的就是一些分佈式服務框架中的服務地址列表。通過調用ZK提供的創建節點的API,能夠很容易創建一個全局唯一的path,這個path就可以作爲一個名稱。
 
分佈式通知/協調
 
ZooKeeper中特有watcher註冊與異步通知機制,能夠很好的實現分佈式環境下不同系統之間的通知與協調,實現對數據變更的實時處理。使用方法通常是不同系統都對ZK上同一個znode進行註冊,監聽znode的變化(包括znode本身內容及子節點的),其中一個系統update了znode,那麼另一個系統能夠收到通知,並作出相應處理
 
1. 另一種心跳檢測機制:檢測系統和被檢測系統之間並不直接關聯起來,而是通過zk上某個節點關聯,大大減少系統耦合。
 
2. 另一種系統調度模式:某系統有控制檯和推送系統兩部分組成,控制檯的職責是控制推送系統進行相應的推送工作。管理人員在控制檯作的一些操作,實際上是修改了ZK上某些節點的狀態,而ZK就把這些變化通知給他們註冊Watcher的客戶端,即推送系統,於是,作出相應的推送任務。
 
3. 另一種工作彙報模式:一些類似於任務分發系統,子任務啓動後,到zk來註冊一個臨時節點,並且定時將自己的進度進行彙報(將進度寫回這個臨時節點),這樣任務管理者就能夠實時知道任務進度。
總之,使用zookeeper來進行分佈式通知和協調能夠大大降低系統之間的耦合
 
集羣管理與Master選舉
 
1. 集羣機器監控:這通常用於那種對集羣中機器狀態,機器在線率有較高要求的場景,能夠快速對集羣中機器變化作出響應。這樣的場景中,往往有一個監控系統,實時檢測集羣機器是否存活。過去的做法通常是:監控系統通過某種手段(比如ping)定時檢測每個機器,或者每個機器自己定時向監控系統彙報“我還活着”。 這種做法可行,但是存在兩個比較明顯的問題:
1. 集羣中機器有變動的時候,牽連修改的東西比較多。
2. 有一定的延時。
 
在分佈式環境中,相同的業務應用分佈在不同的機器上,有些業務邏輯(例如一些耗時的計算,網絡I/O處理),往往只需要讓整個集羣中的某一臺機器進行執行,其餘機器可以共享這個結果,這樣可以大大減少重複勞動,提高性能,於是這個master選舉便是這種場景下的碰到的主要問題。
利用ZooKeeper的強一致性,能夠保證在分佈式高併發情況下節點創建的全局唯一性,即:同時有多個客戶端請求創建 /currentMaster 節點,最終一定只有一個客戶端請求能夠創建成功。利用這個特性,就能很輕易的在分佈式環境中進行集羣選取了。
 
分佈式鎖
 
分佈式鎖,這個主要得益於 ZooKeeper 爲我們保證了數據的強一致性。鎖服務可以分爲兩類,一個是 保持獨佔,另一個是 控制時序。
1. 所謂保持獨佔,就是所有試圖來獲取這個鎖的客戶端,最終只有一個可以成功獲得這把鎖。通常的做法是把 zk 上的一個 znode 看作是一把鎖,通過 create znode 的方式來實現。所有客戶端都去創建 /distribute_lock 節點,最終成功創建的那個客戶端也即擁有了這把鎖。
 
2. 控制時序,就是所有視圖來獲取這個鎖的客戶端,最終都是會被安排執行,只是有個全局時序了。做法和上面基本類似,只是這裏 /distributelock 已經預先存在,客戶端在它下面創建臨時有序節點(這個可以通過節點的屬性控制:CreateMode.EPHEMERALSEQUENTIAL 來指定)。Zk 的父節點(/distribute_lock)維持一份 sequence, 保證子節點創建的時序性,從而也形成了每個客戶端的全局時序。
 
 
Zookeeper有哪幾種節點類型
持久:創建之後一直存在,除非有刪除操作,創建節點的客戶端會話失效也不影響此節點。
持久順序:持久節點名後綴加上一個10位數字。
臨時:創建客戶端會話失效(注意是會話失效,不是連接斷了),節點也就沒了。不能建子節點。
臨時順序:臨時節點名後綴加上一個10位數字。
 
 
Zookeeper對節點的watch監聽通知是永久的嗎?
不是。官方聲明:一個Watch事件是一個一次性的觸發器,當被設置了Watch的數據發生了改變的時候,則服務器將這個改變發送給設置了Watch的客戶端,以便通知它們。
 
爲什麼不是永久的,舉個例子,
如果服務端變動頻繁,而監聽的客戶端很多情況下,每次變動都要通知到所有的客戶端,這太消耗性能了。
一般是客戶端執行getData(“/節點A”,true),如果節點A發生了變更或刪除,客戶端會得到它的watch事件,但是在之後節點A又發生了變更,而客戶端又沒有設置watch事件,就不再給客戶端發送。
在實際應用中,很多情況下,我們的客戶端不需要知道服務端的每一次變動,我只要最新的數據即可。
 
部署方式?集羣中的機器角色都有哪些?集羣最少要幾臺機器
單機,集羣,僞集羣。Leader、Follower、Observer。集羣最低3(2N+1)臺,保證奇數,主要是爲了選舉算法。
 
使用Zookeeper原理
 
» 領導者(leader),負責進行投票的發起和決議,更新系統狀態
» 學習者(learner),包括跟隨者(follower)和觀察者(observer),follower用於接受客戶端請求並想客戶端返回結果,在選主過程中參與投票
» Observer可以接受客戶端連接,將寫請求轉發給leader,但observer不參加投票過程,只同步leader的狀態,observer的目的是爲了擴展系統,提高讀取速度
» 客戶端(client),請求發起方
 
Zookeeper特性
 
1、Zookeeper:一個leader,多個follower組成的集羣
2、全局數據一致:每個server保存一份相同的數據副本,client無論連接到哪個server,數據都是一致的
3、分佈式讀寫,更新請求轉發,由leader實施
4、更新請求順序進行,來自同一個client的更新請求按其發送順序依次執行
5、數據更新原子性,一次數據更新要麼成功,要麼失敗
6、實時性,在一定時間範圍內,client能讀到最新數據
 
集羣支持動態添加機器嗎?
其實就是水平擴容了,Zookeeper在這方面不太好。兩種方式:
全部重啓:關閉所有Zookeeper服務,修改配置之後啓動。不影響之前客戶端的會話。
逐個重啓:這是比較常用的方式。
 
Zookeeper 具有如下特性:
順序一致性(有序性)
從同一個客戶端發起的事務請求,最終將會嚴格地按照其發起順序被應用到 Zookeeper 中去。
有序性是 Zookeeper 中非常重要的一個特性。
 
單一視圖
無論客戶端連接的是哪個 Zookeeper 服務器,其看到的服務端數據模型都是一致的。
 
可靠性
一旦服務端成功地應用了一個事務,並完成對客戶端的響應,那麼該事務所引起的服務端狀態變更將會一直被保留,除非有另一個事務對其進行了變更。
 
實時性
Zookeeper 保證在一定的時間段內,客戶端最終一定能夠從服務端上讀取到最新的數據狀態。
 
Zookeeper 的通知機制是什麼?
Zookeeper 允許客戶端向服務端的某個 znode 註冊一個 Watcher 監聽,當服務端的一些指定事件觸發了這個 Watcher ,服務端會向指定客戶端發送一個事件通知來實現分佈式的通知功能,然後客戶端根據 Watcher 通知狀態和事件類型做出業務上的改變。
 
Zookeeper 的會話管理是怎麼樣的?
ZooKeeper 的每個客戶端都維護一組服務端信息,在創建連接時由應用指定,客戶端隨機選擇一個服務端進行連接,連接成功後,服務端爲每個連接分配一個唯一標識。
 
集羣如果有 3 臺機器,掛掉 1 臺集羣還能工作嗎?掛掉 2 臺呢?
記住一個原則:過半存活即可用。所以掛掉 1 臺可以繼續工作,掛掉 2 臺不可以工作。
 
ZooKeeper 的工作原理?
ZooKeeper 的核心是原子廣播,這個機制保證了各個 Server 之間的同步。實現這個機制的協議叫做 Zab 協議。Zab 協議有兩種模式,它們分別是恢復模式(選主)和廣播模式(同步):
 
Zookeeper 的選舉過程?
當 Leader 崩潰,或者 Leader 失去大多數的 Follower,這時 Zookeeper 進入恢復模式,恢復模式需要重新選舉出一個新的 Leader,讓所有的 Server 都恢復到一個正確的狀態。
 
什麼是分佈式鎖
 
分佈式鎖一般用在分佈式系統或者多個應用中,用來控制同一任務是否執行或者任務的執行順序。在項目中,部署了多個tomcat應用,在執行定時任務時就會遇到同一任務可能執行多次的情況,我們可以藉助分佈式鎖,保證在同一時間只有一個tomcat應用執行了定時任務
 
使用Zookeeper實現分佈式鎖
Zookeeper實現分佈式鎖原理
 
使用zookeeper創建臨時序列節點來實現分佈式鎖,適用於順序執行的程序,大體思路就是創建臨時序列節點,找出最小的序列節點,獲取分佈式鎖,程序執行完成之後此序列節點消失,通過watch來監控節點的變化,從剩下的節點的找到最小的序列節點,獲取分佈式鎖,執行相應處理,依次類推……
 
zk 分佈式鎖
 
1、zk 分佈式鎖,其實可以做的比較簡單,就是某個節點嘗試創建臨時znode,此時創建成功了就獲取了這個鎖;這個時候別的客戶端來創建鎖會失敗,只能註冊個監聽器監聽這個鎖。釋放鎖就是刪除這個 znode,一旦釋放掉就會通知客戶端,然後有一個等待着的客戶端就可以再次重新加鎖。
 
2、如果有一把鎖,被多個人給競爭,此時多個人會排隊,第一個拿到鎖的人會執行,然後釋放鎖;後面的每個人都會去監聽排在自己前面的那個人創建的 node 上,一旦某個人釋放了鎖,排在自己後面的人就會被 ZooKeeper 給通知,一旦被通知了之後,就 ok 了,自己就獲取到了鎖,就可以執行代碼了。
 
使用Zookeeper實現負載均衡原理
 
使用Zookeeper實現負載均衡原理,服務器端將啓動的服務註冊到,zk註冊中心上,採用臨時節點。客戶端從zk節點上獲取最新服務節點信息,本地使用負載均衡算法,隨機分配服務器。
 
 
 
 
 
 
 
 
 
 
 
 
 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章