2020最新Java工程師面試題-ZooKeeper篇(附答案)

持續更新內容涵蓋:Java、MyBatis、ZooKeeper、Dubbo、Elasticsearch、Memcached、Redis、MySQL、Spring、Spring Boot、Spring Cloud、RabbitMQ、Kafka、 Linux 等技術棧(滴滴滴.會持續更新哦,記得點贊、關注、分享三連擊哈).

2020最新Java工程師面試題-ZooKeeper篇(附答案)

1. ZooKeeper 面試題?

ZooKeeper 是一個開放源碼的分佈式協調服務,它是集群的管理者,監視著集群

中各個節點的狀態根據節點提交的反饋進行下一步合理操作。

最終,將簡單易用的接口和性能高效、功能穩定的系統提供給用戶。

分佈式應用程序可以基於 Zookeeper 實現諸如數據發佈/訂閱、負載均衡、命名
服務、分佈式協調/通知、集群管理、Master 選舉、分佈式鎖和分佈式隊列等功能.

Zookeeper 保證瞭如下分佈式一致性特性

1、順序一致性
2、原子性
3、單一視圖
4、可靠性
5、實時性(最終一致性)

客戶端的讀請求可以被集群中的任意一臺機器處理,

如果讀請求在節點上註冊了

監聽器,這個監聽器也是由所連接的 zookeeper 機器來處理

對於寫請求,這些 請求會同時發給其他 zookeeper 機器並且達成一致後,請求才會返回成功.

因此, 隨著 zookeeper 的集群機器增多,讀請求的吞吐會提高但是寫請求的吞吐會下降。

有序性是 zookeeper 中非常重要的一個特性,所有的更新都是全局有序的,每個

更新都有一個唯一的時間戳,這個時間戳稱為 zxid(Zookeeper Transaction Id)。

而讀請求只會相對於更新有序,也就是讀請求的返回結果中會帶有這個zookeeper 最新的 zxid。

2. ZooKeeper 提供了什麼?

1、文件系統

2、通知機制

3. Zookeeper 文件系統

Zookeeper 提供一個多層級的節點命名空間(節點稱為 znode)。

與文件系統不同的是,這些節點都可以設置關聯的數據,而文件系統中只有文件節點可以存放

數據而目錄節點不行。

Zookeeper 為了保證高吞吐和低延遲,在內存中維護了這個樹狀的目錄結構.

這種特性使得 Zookeeper 不能用於存放大量的數據,每個節點的存放數據上限為

1M

4. ZAB 協議?

ZAB 協議是為分佈式協調服務 Zookeeper 專門設計的一種支持崩潰恢復的原子廣

播協議。

ZAB 協議包括兩種基本的模式崩潰恢復和消息廣播

當整個 zookeeper 集群剛剛啟動或者 Leader 服務器宕機、重啟或者網絡故障導

致不存在過半的服務器與 Leader 服務器保持正常通信時,所有進程(服務器)進

入崩潰恢復模式.

首先選舉產生新的 Leader 服務器,然後集群中 Follower 服務器開始與新的 Leader 服務器進行數據同步.
當集群中超過半數機器與該 Leader服務器完成數據同步之後.
退出恢復模式進入消息廣播模式,Leader 服務器開始接收客戶端的事務請求生成事物提案來進行事務請求處理.

5. 四種類型的數據節點 Znode

1、PERSISTENT-持久節點

除非手動刪除,否則節點一直存在於 Zookeeper 上

2、EPHEMERAL-臨時節點

臨時節點的生命週期與客戶端會話綁定,一旦客戶端會話失效(客戶端與

zookeeper 連接斷開不一定會話失效),那麼這個客戶端創建的所有臨時節點都

會被移除。

3、PERSISTENT_SEQUENTIAL-持久順序節點

基本特性同持久節點,只是增加了順序屬性,節點名後邊會追加一個由父節點維

護的自增整型數字。

4、EPHEMERAL_SEQUENTIAL-臨時順序節點

基本特性同臨時節點,增加了順序屬性,節點名後邊會追加一個由父節點維護的

自增整型數字。

6. Zookeeper Watcher 機制 -- 數據變更通知

Zookeeper 允許客戶端向服務端的某個 Znode 註冊一個 Watcher 監聽,當服務

端的一些指定事件觸發了這個 Watcher,服務端會向指定客戶端發送一個事件通

知來實現分佈式的通知功能,然後客戶端根據 Watcher 通知狀態和事件類型做出

業務上的改變。

工作機制

1、客戶端註冊 watcher
2、服務端處理 watcher
3、客戶端回調 watcher

Watcher 特性總結

1、一次性

無論是服務端還是客戶端,一旦一個 Watcher 被觸發,Zookeeper 都會將其從相

應的存儲中移除。

這樣的設計有效的減輕了服務端的壓力,不然對於更新非常頻繁的節點.

服務端會不斷的向客戶端發送事件通知,無論對於網絡還是服務端的壓力都非常大。

2、客戶端串行執行

客戶端 Watcher 回調的過程是一個串行同步的過程。

3、輕量

3.1、Watcher 通知非常簡單,只會告訴客戶端發生了事件,而不會說明事件的具

體內容。

3.2、客戶端向服務端註冊 Watcher 的時候,並不會把客戶端真實的 Watcher 對

象實體傳遞到服務端,僅僅是在客戶端請求中使用 boolean 類型屬性進行了標記。

4、watcher event 異步發送 watcher 的通知事件從 server 發送到 client 是異步

的,這就存在一個問題,不同的客戶端和服務器之間通過 socket 進行通信,由於

網絡延遲或其他因素導致客戶端在不通的時刻監聽到事件,由於 Zookeeper 本身

提供了 ordering guarantee,即客戶端監聽事件後,才會感知它所監視 znode

發生了變化。所以我們使用 Zookeeper 不能期望能夠監控到節點每次的變化。

Zookeeper 只能保證最終的一致性,而無法保證強一致性。

5、註冊 watcher getData、exists、getChildren

6、觸發 watcher create、delete、setData

7、當一個客戶端連接到一個新的服務器上時,watch 將會被以任意會話事件觸發。

當與一個服務器失去連接的時候,是無法接收到 watch 的。而當 client 重新連接

時,如果需要的話,所有先前註冊過的 watch,都會被重新註冊。通常這是完全

透明的。只有在一個特殊情況下,watch 可能會丟失:對於一個未創建的 znode

的 exist watch,如果在客戶端斷開連接期間被創建了,並且隨後在客戶端連接上

之前又刪除了,這種情況下,這個 watch 事件可能會被丟失。

7. 客戶端註冊 Watcher 實現

1、調用 getData()/getChildren()/exist()三個 API,傳入 Watcher 對象

2、標記請求 request,封裝 Watcher 到 WatchRegistration

3、封裝成 Packet 對象,發服務端發送 request

4、收到服務端響應後,將 Watcher 註冊到 ZKWatcherManager 中進行管理

5、請求返回,完成註冊。

8. 服務端處理 Watcher 實現

1、服務端接收 Watcher 並存儲

接收到客戶端請求,處理請求判斷是否需要註冊 Watcher,需要的話將數據節點

的節點路徑和 ServerCnxn(ServerCnxn 代表一個客戶端和服務端的連接,實現

了 Watcher 的 process 接口,此時可以看成一個 Watcher 對象)存儲在

WatcherManager 的 WatchTable 和 watch2Paths 中去。

2、Watcher 觸發

以服務端接收到 setData() 事務請求觸發 NodeDataChanged 事件為例:

2.1 封裝 WatchedEvent

將通知狀態(SyncConnected)、事件類型(NodeDataChanged)以及節點路

徑封裝成一個 WatchedEvent 對象

2.2 查詢 Watcher

從 WatchTable 中根據節點路徑查找 Watcher

2.3 沒找到;說明沒有客戶端在該數據節點上註冊過 Watcher

2.4 找到;提取並從 WatchTable 和 Watch2Paths 中刪除對應 Watcher(從這裡

可以看出 Watcher 在服務端是一次性的,觸發一次就失效了

3、調用 process 方法來觸發 Watcher

這裡 process 主要就是通過 ServerCnxn 對應的 TCP 連接發送 Watcher 事件通知。

9. 客戶端回調 Watcher

客戶端 SendThread 線程接收事件通知,交由 EventThread 線程回調 Watcher。

客戶端的 Watcher 機制同樣是一次性的,一旦被觸發後,該 Watcher 就失效了。

10. ACL 權限控制機制

UGO(User/Group/Others)

目前在 Linux/Unix 文件系統中使用,也是使用最廣泛的權限控制方式。是一種粗

粒度的文件系統權限控制模式。

ACL(Access Control List)訪問控制列表

包括三個方面

權限模式(Scheme)

1、IP:從 IP 地址粒度進行權限控制
2、Digest:最常用,用類似於 username:password 的權限標識來進行權限配
置,便於區分不同應用來進行權限控制
3、World:最開放的權限控制方式,是一種特殊的 digest 模式,只有一個權限標
識“world:anyone”

4、Super:超級用戶

授權對象指的是權限賦予的用戶或一個指定實體,例如 IP 地址或是機器燈。

權限 Permission

1、CREATE:數據節點創建權限,允許授權對象在該 Znode 下創建子節點

2、DELETE:子節點刪除權限,允許授權對象刪除該數據節點的子節點

3、READ:數據節點的讀取權限,允許授權對象訪問該數據節點並讀取其數據內

容或子節點列表等

4、WRITE:數據節點更新權限,允許授權對象對該數據節點進行更新操作

5、ADMIN:數據節點管理權限,允許授權對象對該數據節點進行 ACL 相關設置

操作

11. Chroot 特性

3.2.0 版本後,添加了 Chroot 特性,該特性允許每個客戶端為自己設置一個命名

空間。如果一個客戶端設置了 Chroot,那麼該客戶端對服務器的任何操作,都將

會被限制在其自己的命名空間下。

通過設置 Chroot,能夠將一個客戶端應用於 Zookeeper 服務端的一顆子樹相對

應,在那些多個應用公用一個 Zookeeper 進群的場景下,對實現不同應用間的相

互隔離非常有幫助。

12. 會話管理

分桶策略:將類似的會話放在同一區塊中進行管理,以便於 Zookeeper 對會話進

行不同區塊的隔離處理以及同一區塊的統一處理。

分配原則

:每個會話的“下次超時時間點”(ExpirationTime)

計算公式:

ExpirationTime_ = currentTime + sessionTimeout
ExpirationTime = (ExpirationTime_ / ExpirationInrerval + 1) *
ExpirationInterval , ExpirationInterval
是指 Zookeeper 會話超時檢查時間 間隔,默認 tickTime

13. 服務器角色

Leader

1、事務請求的唯一調度和處理者,保證集群事務處理的順序性

2、集群內部各服務的調度者

Follower

1、處理客戶端的非事務請求,轉發事務請求給 Leader 服務器

2、參與事務請求 Proposal 的投票

3、參與 Leader 選舉投票

Observer

1、3.0 版本以後引入的一個服務器角色,在不影響集群事務處理能力的基礎上提

升集群的非事務處理能力

2、處理客戶端的非事務請求,轉發事務請求給 Leader 服務器

3、不參與任何形式的投票

14. Zookeeper 下 Server 工作狀態

服務器具有四種狀態,分別是 LOOKING、FOLLOWING、LEADING、OBSERVING。

1、LOOKING:尋找 Leader 狀態。當服務器處於該狀態時,它會認為當前集群中

沒有 Leader,因此需要進入 Leader 選舉狀態。

2、FOLLOWING:跟隨者狀態。表明當前服務器角色是 Follower。

3、LEADING:領導者狀態。表明當前服務器角色是 Leader。

4、OBSERVING:觀察者狀態。表明當前服務器角色是 Observer。

15. 數據同步

整個集群完成 Leader 選舉之後,Learner(Follower 和 Observer 的統稱)迴向

Leader 服務器進行註冊。當 Learner 服務器想 Leader 服務器完成註冊後,進入

數據同步環節。

數據同步流程:(均以消息傳遞的方式進行)

Learner 向 Learder 註冊

數據同步
同步確認

Zookeeper 的數據同步通常分為四類

1、直接差異化同步(DIFF 同步)
2、先回滾再差異化同步(TRUNC+DIFF 同步)
3、僅回滾同步(TRUNC 同步)
4、全量同步(SNAP 同步)

在進行數據同步前,Leader 服務器會完成數據同步初始化:

peerLastZxid:

從 learner 服務器註冊時發送的 ACKEPOCH 消息中提取 lastZxid(該

Learner 服務器最後處理的 ZXID)

minCommittedLog:

Leader 服務器 Proposal 緩存隊列 committedLog 中最小 ZXID

maxCommittedLog:

Leader 服務器 Proposal 緩存隊列 committedLog 中最大 ZXID

直接差異化同步(DIFF 同步)

場景:peerLastZxid 介於 minCommittedLog 和 maxCommittedLog

之間

先回滾再差異化同步(TRUNC+DIFF 同步)

場景:當新的 Leader 服務器發現某個 Learner 服務器包含了一條自己沒

有的事務記錄,那麼就需要讓該 Learner 服務器進行事務回滾--回滾到 Leader

服務器上存在的,同時也是最接近於 peerLastZxid 的 ZXID

僅回滾同步(TRUNC 同步)第 61 頁 共 485 頁

場景:peerLastZxid 大於 maxCommittedLog

全量同步(SNAP 同步)

場景一:peerLastZxid 小於 minCommittedLog

場景二:Leader 服務器上沒有 Proposal 緩存隊列且 peerLastZxid 不等

於 lastProcessZxid

16. zookeeper 是如何保證事務的順序一致性的?

zookeeper 採用了全局遞增的事務 Id 來標識,所有的 proposal(提議)都在被

提出的時候加上了 zxid,zxid 實際上是一個 64 位的數字,高 32 位是 epoch(時

期; 紀元; 世; 新時代)用來標識 leader 週期,如果有新的 leader 產生出來,epoch

會自增,低 32 位用來遞增計數。

當新產生 proposal 的時候,會依據數據庫的兩階段過程,首先會向其他的 server 發出事務執行請求,如果超過半數的機器都能執行並且能夠成功,那麼就會開始執行。

17. 分佈式集群中為什麼會有 Master?

在分佈式環境中,有些業務邏輯只需要集群中的某一臺機器進行執行,其他的機

器可以共享這個結果,這樣可以大大減少重複計算,提高性能,於是就需要進行

leader 選舉。

18. zk 節點宕機如何處理?

Zookeeper 本身也是集群,推薦配置不少於 3 個服務器。Zookeeper 自身也要保

證當一個節點宕機時,其他節點會繼續提供服務。

如果是一個 Follower 宕機,還有 2 臺服務器提供訪問,因為 Zookeeper 上的數

據是有多個副本的,數據並不會丟失;

如果是一個 Leader 宕機,Zookeeper 會選舉出新的 Leader。

ZK 集群的機制是隻要超過半數的節點正常,集群就能正常提供服務。只有在 ZK

節點掛得太多,只剩一半或不到一半節點能工作,集群才失效。

所以

3 個節點的 cluster 可以掛掉 1 個節點(leader 可以得到 2 票>1.5)

2 個節點的 cluster 就不能掛掉任何 1 個節點了(leader 可以得到 1 票<=1)

19. zookeeper 負載均衡和 nginx 負載均衡區別

zk 的負載均衡是可以調控,nginx 只是能調權重,其他需要可控的都需要自己寫

插件;但是 nginx 的吞吐量比 zk 大很多,應該說按業務選擇用哪種方式。

20. Zookeeper 有哪幾種幾種部署模式?

部署模式:單機模式、偽集群模式、集群模式。

21. 集群最少要幾臺機器,集群規則是怎樣的?

集群規則為 2N+1 臺,N>0,即 3 臺.

22. 集群支持動態添加機器嗎?

其實就是水平擴容了,Zookeeper 在這方面不太好。兩種方式:

全部重啟:關閉所有 Zookeeper 服務,修改配置之後啟動。不影響之前客戶端的

會話。

逐個重啟:在過半存活即可用的原則下,一臺機器重啟不影響整個集群對外提供

服務。這是比較常用的方式。

3.5 版本開始支持動態擴容。

23. Zookeeper 對節點的 watch監聽通知是永久的嗎?為什麼

不是永久的?

不是。官方聲明:一個 Watch 事件是一個一次性的觸發器,當被設置了 Watch

的數據發生了改變的時候,則服務器將這個改變發送給設置了 Watch 的客戶端,

以便通知它們。

為什麼不是永久的,舉個例子,如果服務端變動頻繁,而監聽的客戶端很多情況

下,每次變動都要通知到所有的客戶端,給網絡和服務器造成很大壓力。

一般是客戶端執行 getData(“/節點 A”,true),如果節點 A 發生了變更或刪除,

客戶端會得到它的 watch 事件,但是在之後節點 A 又發生了變更,而客戶端又沒

有設置 watch 事件,就不再給客戶端發送。

在實際應用中,很多情況下,我們的客戶端不需要知道服務端的每一次變動,我

只要最新的數據即可。

24. Zookeeper 的 java 客戶端都有哪些?

java 客戶端:zk 自帶的 zkclient 及 Apache 開源的 Curator。

25. chubby 是什麼,和 zookeeper 比你怎麼看?

chubby 是 google 的,完全實現 paxos 算法,不開源。zookeeper 是 chubby

的開源實現,使用 zab 協議,paxos 算法的變種。

26. 說幾個 zookeeper 常用的命令。

常用命令:ls get set create delete 等。

27. ZAB 和 Paxos 算法的聯繫與區別?

相同點

1、兩者都存在一個類似於 Leader 進程的角色,由其負責協調多個 Follower 進程

的運行

2、Leader 進程都會等待超過半數的 Follower 做出正確的反饋後,才會將一個提

案進行提交

3、ZAB 協議中,每個 Proposal 中都包含一個 epoch 值來代表當前的 Leader

週期,Paxos 中名字為 Ballot

不同點

ZAB 用來構建高可用的分佈式數據主備系統(Zookeeper),Paxos 是用來構建

分佈式一致性狀態機系統。

28. Zookeeper 的典型應用場景

Zookeeper 是一個典型的發佈/訂閱模式的分佈式數據管理與協調框架,開發人員

可以使用它來進行分佈式數據的發佈和訂閱。

通過對 Zookeeper 中豐富的數據節點進行交叉使用,配合 Watcher 事件通知機

制,可以非常方便的構建一系列分佈式應用中年都會涉及的核心功能,如:

1、數據發佈/訂閱
2、負載均衡
3、命名服務
4、分佈式協調/通知
5、集群管理
6、Master 選舉
7、分佈式鎖
8、分佈式隊列

1. 數據發佈/訂閱

介紹

數據發佈/訂閱系統,即所謂的配置中心,顧名思義就是發佈者發佈數據供訂閱者

進行數據訂閱。

目的

動態獲取數據(配置信息)

實現數據(配置信息)的集中式管理和數據的動態更新

設計模式

Push 模式
Pull 模式

數據(配置信息)特性

1、數據量通常比較小

2、數據內容在運行時會發生動態更新

3、集群中各機器共享,配置一致

如:機器列表信息、運行時開關配置、數據庫配置信息等

基於 Zookeeper 的實現方式

數據存儲:將數據(配置信息)存儲到 Zookeeper 上的一個數據節點

數據獲取:應用在啟動初始化節點從 Zookeeper 數據節點讀取數據,並

在該節點上註冊一個數據變更 Watcher

數據變更:當變更數據時,更新 Zookeeper 對應節點數據,Zookeeper

會將數據變更通知發到各客戶端,客戶端接到通知後重新讀取變更後的數據即

可。

2. 負載均衡

zk 的命名服務

命名服務是指通過指定的名字來獲取資源或者服務的地址,利用 zk 創建一個全局

的路徑,這個路徑就可以作為一個名字,指向集群中的集群,提供的服務的地址,

或者一個遠程的對象等等。

分佈式通知和協調

對於系統調度來說:操作人員發送通知實際是通過控制檯改變某個節點的狀態,

然後 zk 將這些變化發送給註冊了這個節點的 watcher 的所有客戶端。對於執行情況彙報:每個工作進程都在某個目錄下創建一個臨時節點。並攜帶工

作的進度數據,這樣彙總的進程可以監控目錄子節點的變化獲得工作進度的實時

的全局情況。

zk 的命名服務(文件系統)

命名服務是指通過指定的名字來獲取資源或者服務的地址,利用 zk 創建一個全局

的路徑,即是唯一的路徑,這個路徑就可以作為一個名字,指向集群中的集群,

提供的服務的地址,或者一個遠程的對象等等。

zk 的配置管理(文件系統、通知機制)

程序分佈式的部署在不同的機器上,將程序的配置信息放在 zk 的 znode 下,當有

配置發生改變時,也就是 znode 發生變化時,可以通過改變 zk 中某個目錄節點的

內容,利用 watcher 通知給各個客戶端,從而更改配置。

Zookeeper 集群管理(文件系統、通知機制)

所謂集群管理無在乎兩點:是否有機器退出和加入、選舉 master。

對於第一點,所有機器約定在父目錄下創建臨時目錄節點,然後監聽父目錄節點

的子節點變化消息。一旦有機器掛掉,該機器與 zookeeper 的連接斷開,其所創

建的臨時目錄節點被刪除,所有其他機器都收到通知:某個兄弟目錄被刪除,於

是,所有人都知道:它上船了。

新機器加入也是類似,所有機器收到通知:新兄弟目錄加入,highcount 又有了,

對於第二點,我們稍微改變一下,所有機器創建臨時順序編號目錄節點,每次選

取編號最小的機器作為 master 就好。

Zookeeper 分佈式鎖(文件系統、通知機制)

有了 zookeeper 的一致性文件系統,鎖的問題變得容易。鎖服務可以分為兩類,

一個是保持獨佔,另一個是控制時序。

對於第一類,我們將 zookeeper 上的一個 znode 看作是一把鎖,通過 createznode

的方式來實現。所有客戶端都去創建 /distribute_lock 節點,最終成功創建的那

個客戶端也即擁有了這把鎖。用完刪除掉自己創建的 distribute_lock 節點就釋放

出鎖。

對於第二類, /distribute_lock 已經預先存在,所有客戶端在它下面創建臨時順

序編號目錄節點,和選 master 一樣,編號最小的獲得鎖,用完刪除,依次方便。

Zookeeper 隊列管理(文件系統、通知機制)

兩種類型的隊列:

1、同步隊列,當一個隊列的成員都聚齊時,這個隊列才可用,否則一直等待所有

成員到達。

2、隊列按照 FIFO 方式進行入隊和出隊操作。

第一類,在約定目錄下創建臨時目錄節點,監聽節點數目是否是我們要求的數目。

第二類,和分佈式鎖服務中的控制時序場景基本原理一致,入列有編號,出列按

編號。在特定的目錄下創建 PERSISTENT_SEQUENTIAL 節點,創建成功時

Watcher 通知等待的隊列,隊列刪除序列號最小的節點用以消費。

此場景下Zookeeper 的 znode 用於消息存儲,znode 存儲的數據就是消息隊列中的消息內

容,SEQUENTIAL 序列號就是消息的編號,按序取出即可。由於創建的節點是持久化的,所以不必擔心隊列消息的丟失問題。 下面展示了部分資料,也希望也能幫助到大家,對編程感興趣想進階的朋友,如果能幫到你請點贊、點贊、點贊:

整理的 pdf 文檔:

2020最新Java工程師面試題-ZooKeeper篇(附答案)

2020最新Java工程師面試題-ZooKeeper篇(附答案)

2020最新Java工程師面試題-ZooKeeper篇(附答案)

2020最新Java工程師面試題-ZooKeeper篇(附答案)

源碼分析專題部分課程:

2020最新Java工程師面試題-ZooKeeper篇(附答案)

2020最新Java工程師面試題-ZooKeeper篇(附答案)

獲取方式

點贊,收藏並轉發文章後點擊小編頭像或暱稱,關注後私信回覆:【11】 即可

舉手之勞,非常感謝!!!


分享到:


相關文章: