你們好,我是Java最全面試題庫
的提褲姐,今天這篇是JavaEE面試題系列的第十二篇,主要總結了ZooKeeper相關的面試題;在後續,會沿着第一篇開篇的知識線路一直總結下去,作到日更!若是我能作到百日百更,但願你也能夠跟着百日百刷,一百天養成一個好習慣。java
ZooKeeper是一個開放源碼的分佈式協調服務
,它是集羣的管理者,監視着集羣中各個節點的狀態根據節點提交的反饋進行下一步合理操做。最終,將簡單易用的接口和性能高效、功能穩定的系統提供給用戶。node
分佈式應用程序能夠基於Zookeeper實現諸如數據發佈/訂閱、負載均衡、命名服務、分佈式協調/通知、集羣管理、Master選舉、分佈式鎖和分佈式隊列等功能。面試
Zookeeper保證了以下分佈式一致性特性:服務器
客戶端的讀請求能夠被集羣中的任意一臺機器處理,若是讀請求在節點上註冊了監聽器,這個監聽器也是由所鏈接的zookeeper機器來處理。對於寫請求,這些請求會同時發給其餘zookeeper機器而且達成一致後,請求才會返回成功。所以,隨着zookeeper的集羣機器增多,讀請求的吞吐會提升可是寫請求的吞吐會降低。網絡
有序性是zookeeper中很是重要的一個特性,全部的更新都是全局有序的,每一個更新都有一個惟一的時間戳,這個時間戳稱爲zxid(Zookeeper Transaction Id)
。而讀請求只會相對於更新有序,也就是讀請求的返回結果中會帶有這個zookeeper最新的zxid。併發
Zookeeper:
zookeeper用來註冊服務和進行負載均衡,哪個服務由哪個機器來提供必需讓調用者知道,
簡單來講就是ip地址和服務名稱的對應關係。固然也能夠經過硬編碼的方式把這種對應關係在調用方業務代碼中實現,可是若是提供服務的機器掛掉,調用者沒法知曉,若是不更改代碼會繼續請求掛掉的機器提供服務。 zookeeper經過心跳機制
能夠檢測掛掉的機器並將掛掉機器的ip和服務對應關係從列表中刪除。至於支持高併發,簡單來講就是橫向擴展,在不更改代碼的狀況經過添加機器來提升運算能力。經過添加新的機器向 zookeeper註冊服務,服務的提供者多了能服務的客戶就多了。負載均衡
dubbo:
是管理中間層的工具,在業務層到數據倉庫間有很是多服務的接入和服務提供者須要調度,dubbo提供一個框架解決這個問題。框架
zookeeper和 dubbo的關係:
Dubbo將註冊中心進行抽象,它能夠外接不一樣的存儲媒介給註冊中心提供服務,有 ZooKeeper, Memcached, Redis等。分佈式
注意這裏的 dubbo只是一個框架,這個框架中要完成調度必需要有一個分佈式的註冊中心,儲存全部服務的元數據,能夠用zk,也能夠用別的。
Zookeeper提供一個多層級的節點命名空間(節點稱爲 znode)。與文件系統不一樣的是,這些節點均可以設置關聯的數據,而文件系統中只有文件節點能夠存放數據而目錄節點不行。高併發
Zookeeper爲了保證高吞吐和低延遲,在內存中維護了這個樹狀的目錄結構,這種特性使得 Zookeeper不能用於存放大量的數據,每一個節點的存放數據上限爲1M。
ZAB協議是爲分佈式協調服務Zookeeper專門設計的一種支持崩潰恢復的原子廣播協議
。
ZAB協議包括兩種基本的模式:崩潰恢復
和消息廣播
。
當整個zookeeper集羣剛剛啓動或者Leader服務器宕機、重啓或者網絡故障致使不存在過半的服務器與Leader服務器保持正常通訊時,全部進程(服務器)進入崩潰恢復模式,首先選舉產生新的Leader服務器,而後集羣中Follower服務器開始與新的Leader服務器進行數據同步,當集羣中超過半數機器與該Leader服務器完成數據同步以後,退出恢復模式進入消息廣播模式,Leader服務器開始接收客戶端的事務請求生成事物提案來進行事務請求處理。
PERSISTENT-持久節點
除非手動刪除,不然節點一直存在於Zookeeper上
EPHEMERAL-臨時節點
臨時節點的生命週期與客戶端會話綁定,一旦客戶端會話失效(客戶端與zookeeper鏈接斷開不必定會話失效),那麼這個客戶端建立的全部臨時節點都會被移除。
PERSISTENT_SEQUENTIAL-持久順序節點
基本特性同持久節點,只是增長了順序屬性,節點名後邊會追加一個由父節點維護的自增整型數字。
EPHEMERAL_SEQUENTIAL-臨時順序節點
基本特性同臨時節點,增長了順序屬性,節點名後邊會追加一個由父節點維護的自增整型數字。
Zookeeper自己也是集羣,推薦配置很多於3個服務器
。Zookeeper自身也要保證當一個節點宕機時,其餘節點會繼續提供服務。
若是是一個Follower宕機,還有2臺服務器提供訪問,由於Zookeeper上的數據是有多個副本的,數據並不會丟失;
若是是一個Leader宕機,Zookeeper會選舉出新的Leader。
ZK集羣的機制是隻要超過半數的節點正常,集羣就能正常提供服務。
只有在ZK節點掛得太多,只剩一半或不到一半節點能工做,集羣才失效。
因此:
Zookeeper有三種部署模式:
單機部署
:一臺集羣上運行集羣部署
:多臺集羣運行僞集羣部署
:一臺集羣啓動多個 Zookeeper實例運行Zookeeper是一個典型的發佈/訂閱模式
的分佈式數據管理與協調框架,開發人員可使用它來進行分佈式數據的發佈和訂閱。
經過對 Zookeeper中豐富的數據節點進行交叉使用,配合 Watcher事件通知機制
,能夠很是方便的構建一系列分佈式應用,會涉及的核心功能:
Zookeeper容許客戶端向服務端的某個 Znode註冊個 Watcher監聽,當服務端的一些指定事件觸發了這個 Watcher,服務端會向指定客戶端發送一個事件通知來實現分佈式的通知功能,客戶端根據 Watcher通知狀態和事件類型作出業務上的改變。
工做機制:
一、客戶端註冊Watcher實現
二、調用getData()
/getChildren()
/exist()
三個API,傳入Watcher對象
三、標記請求request,封裝Watcher到WatchRegistration
四、封裝成Packet
對象,發服務端發送request
五、收到服務端響應後,將Watcher註冊到ZKWatcherManager
中進行管理
六、請求返回,完成註冊。
一、服務端接收Watcher並存儲
接收到客戶端請求,處理請求判斷是否須要註冊Watcher,須要的話將數據節點的節點路徑和ServerCnxn(ServerCnxn表明一個客戶端和服務端的鏈接,實現了Watcher的process接口,此時能夠當作一個Watcher對象)存儲在WatcherManager的WatchTable和watch2Paths中去。
二、Watcher觸發
沒找到;說明沒有客戶端在該數據節點上註冊過Watcher
找到;提取並從WatchTable和Watch2Paths中刪除對應Watcher(從這裏能夠看出Watcher在服務端是一次性的,觸發一次就失效了)
三、調用process方法來觸發Watcher
這裏process主要就是經過ServerCnxn對應的TCP鏈接發送Watcher事件通知。
一、客戶端SendThread
線程接收事件通知,交由 EventThread線程回調 Watcher。
二、客戶端的Watcher機制一樣是一次性的,一旦被觸發後,該 Watcher就失效了。
不是永久的。
官方聲明:一個 Watch事件是一個次性的觸發器,當被設置了 Watch的數據發生了改變的時候,則服務器將這個改變發送給設置了 Watch的客戶端,以便通知它們。
緣由:
若是服務端變更頻繁,而監聽的客戶端不少狀況下,每次變更都要通知到全部的客戶端,給網絡和服務器形成很大壓力。通常是客戶端執行getData
(「/節點」,true),若是節點A發生了變動或刪除,客戶端會獲得它的 watch事件,可是在以後節點A又發生了變動,而客戶端又沒有設置 watch事件,就再也不給客戶端發送。
在實際應用中,不少狀況下,咱們的客戶端不須要知道服務端的每一次變更,我只要最新的數據便可。
一、權限模式(Scheme)
IP:從IP地址粒度進行權限控制
Digest:最經常使用,用相似於 username:password 的權限標識來進行權限配置,便於區分不一樣應用來進行權限控制
World:最開放的權限控制方式,是一種特殊的digest模式,只有一個權限標識「world:anyone」
Super:超級用戶
二、受權對象
受權對象指的是權限賦予的用戶或一個指定實體,例如IP地址或是機器燈。
三、權限 Permission
一、Leader
事務請求的惟一調度和處理者,保證集羣事務處理的順序性
集羣內部各服務的調度者
二、Follower
處理客戶端的非事務請求,轉發事務請求給Leader服務器
參與事務請求Proposal的投票
參與Leader選舉投票
三、Observer
處理客戶端的非事務請求,轉發事務請求給Leader服務器
不參與任何形式的投票
一、LOOKING
:尋找Leader狀態。當服務器處於該狀態時,它會認爲當前集羣中沒有Leader,所以須要進入Leader選舉狀態。
二、FOLLOWING
:跟隨者狀態。代表當前服務器角色是Follower。
三、LEADING
:領導者狀態。代表當前服務器角色是Leader。
四、OBSERVING
:觀察者狀態。代表當前服務器角色是Observer。
其實就是水平擴容,Zookeeper在這方面不太好。
兩種方式:
所有重啓
:關閉全部 Zookeeper服務,修改配置以後啓動。不影響以前客戶端的會話。逐個重啓
:在過半存活便可用的原則下一臺機器重啓不影響整個集羣對外提供服務。(這是比較經常使用的方式)3.5版本開始支持動態擴容。
3.2.0版本後,添加了特性,該特性容許每一個客戶端爲本身設置一個命名空間。若是一個客戶端設置了 Chroot,那麼該客戶端對服務器的任何操做,都將會被限制在其本身的命名空間下。
經過設置 Chroot,可以將一個客戶端應用與 Zookeeper服務端的一顆子樹相對應,在那些多個應用公用一個 Zookeeper集羣的場景下,對實現不一樣應用間的相互隔離很是有幫助。