Zookeeper面試題總結


1、請簡述Zookeeper的選舉機制

假設有五台服務器組成的zookeeper集群,它們的id從1-5,同時它們都是最新啟動的,也就是沒有歷史數據,在存放數據量這一點上,都是一樣的。
假設這些服務器依序啟動,來看看會發生什么。
ZK選舉機制
(1)服務器1啟動,此時只有它一台服務器啟動了,它發出去的報沒有任何響應,所以它的選舉狀態一直是LOOKING狀態。
(2)服務器2啟動,它與最開始啟動的服務器1進行通信,互相交換自己的選舉結果,由於兩者都沒有歷史數據,所以id值較大的服務器2勝出,
但是由於沒有達到超過半數以上的服務器都同意選舉它(這個例子中的半數以上是3),所以服務器1、2還是繼續保持LOOKING狀態。
(3)服務器3啟動,根據前面的理論分析,服務器3成為服務器1、2、3中的Leader,而與上面不同的是,此時有三台服務器選舉了它,
所以它成為了這次選舉的Leader。
(4)服務器4啟動,根據前面的分析,理論上服務器4應該是服務器1、2、3、4中最大的,但是由於前面已經有半數以上的服務器選舉了服務器3,
所以它成為Follower。
(5)服務器5啟動,同4一樣成為Follower。
注意,如果按照5,4,3,2,1的順序啟動,那么5將成為Leader,因為在滿足半數條件后,ZooKeeper集群啟動,5的Id最大,被選舉為Leader。

2、客戶端如何正確處理CONNECTIONLOSS(連接斷開) 和 SESSIONEXPIRED(Session 過期)兩類連接異常?

在ZooKeeper中,服務器和客戶端之間維持的是一個長連接,在 SESSION_TIMEOUT 時間內,服務器會確定客戶端是否正常連接(客戶端會定時向服務器發送
heart_beat),服務器重置下次SESSION_TIMEOUT時間。因此,在正常情況下,Session一直有效,並且zk集群所有機器上都保存這個Session信息。在出現問題的情況下,
客戶端與服務器之間連接斷了(客戶端所連接的那台zk機器掛了,或是其它原因的網絡閃斷),這個時候客戶端會主動在地址列表(初始化的時候傳入構造方法的那個
參數connectString)中選擇新的地址進行連接。
以上即為服務器與客戶端之間維持長連接的過程,在這個過程中,用戶可能會看到兩類異常CONNECTIONLOSS(連接斷開) 和SESSIONEXPIRED(Session 過期)。
發生CONNECTIONLOSS后,此時用戶不需要關心我的會話是否可用,應用所要做的就是等待客戶端幫我們自動連接上新的zk機器,一旦成功連接上新的zk機器后,
確認之前的操作是否執行成功了

3、一個客戶端修改了某個節點的數據,其他客戶端能夠馬上獲取到這個最新數據嗎?

ZooKeeper不能確保任何客戶端能夠獲取(即Read Request)到一樣的數據,除非客戶端自己要求,方法是客戶端在獲取數據之前調用
org.apache.zookeeper.AsyncCallbac k.VoidCallback, java.lang.Object) sync。
通常情況下(這里所說的通常情況滿足:1. 對獲取的數據是否是最新版本不敏感,2. 一個客戶端修改了數據,其它客戶端是否需要立即能夠獲取最新數據),
可以不關心這點。
在其它情況下,最清晰的場景是這樣:ZK客戶端A對 /my_test 的內容從 v1->v2, 但是ZK客戶端B對 /my_test 的內容獲取,依然得到的是 v1. 請注意,
這個是實際存在的現象,當然延時很短。解決的方法是客戶端B先調用 sync(), 再調用 getData()

4、ZooKeeper對節點的watch監聽是永久的嗎?為什么?

不是。
官方聲明:一個Watch事件是一個一次性的觸發器,當被設置了Watch的數據發生了改變的時候,則服務器將這個改變發送給設置了Watch的客戶端,
以便通知它們。
為什么不是永久的,舉個例子,如果服務端變動頻繁,而監聽的客戶端很多情況下,每次變動都要通知到所有的客戶端,這太消耗性能了。
一般是客戶端執行getData(“/節點A”,true),如果節點A發生了變更或刪除,客戶端會得到它的watch事件,但是在之后節點A又發生了變更,
而客戶端又沒有設置watch事件,就不再給客戶端發送。
在實際應用中,很多情況下,我們的客戶端不需要知道服務端的每一次變動,我只要最新的數據即可。

5、ZooKeeper中使用watch的注意事項有哪些?

使用watch需要注意的幾點:
1)Watches通知是一次性的,必須重復注冊。
2)發生CONNECTIONLOSS之后,只要在session_timeout之內再次連接上(即不發生SESSIONEXPIRED),那么這個連接注冊的watches依然在。
3)節點數據的版本變化會觸發NodeDataChanged,注意,這里特意說明了是版本變化。存在這樣的情況,只要成功執行了setData()方法,
無論內容是否和之前一致,都會觸發NodeDataChanged。
4)對某個節點注冊了watch,但是節點被刪除了,那么注冊在這個節點上的watches都會被移除。
5)同一個zk客戶端對某一個節點注冊相同的watch,只會收到一次通知。
6)Watcher對象只會保存在客戶端,不會傳遞到服務端。

6、能否收到每次節點變化的通知?

如果節點數據的更新頻率很高的話,不能。
原因在於:當一次數據修改,通知客戶端,客戶端再次注冊watch,在這個過程中,可能數據已經發生了許多次數據修改,因此,
千萬不要做這樣的測試:”數據被修改了n次,一定會收到n次通知”來測試server是否正常工作。

7、能否為臨時節點創建子節點?

ZooKeeper中不能為臨時節點創建子節點,如果需要創建子節點,應該將要創建子節點的節點創建為永久性節點。

8、是否可以拒絕單個IP對ZooKeeper的訪問?

如何實現?ZK本身不提供這樣的功能,它僅僅提供了對單個IP的連接數的限制。你可以通過修改iptables來實現對單個ip的限制。

9、創建的臨時節點什么時候會被刪除,是連接一斷就刪除嗎?

延時是多少?連接斷了之后,ZK不會馬上移除臨時數據,只有當SESSIONEXPIRED之后,才會把這個會話建立的臨時數據移除。因此,
用戶需要謹慎設置Session_TimeOut。

10、ZooKeeper是否支持動態進行機器擴容?如果目前不支持,那么要如何擴容呢?

ZooKeeper中的動態擴容其實就是水平擴容,Zookeeper對這方面的支持不太好,目前有兩種方式:
全部重啟:關閉所有Zookeeper服務,修改配置之后啟動,不影響之前客戶端的會話。
逐個重啟:這是比較常用的方式。

11、ZooKeeper集群中服務器之間是怎樣通信的?

Leader服務器會和每一個Follower/Observer服務器都建立TCP連接,同時為每個F/O都創建一個叫做LearnerHandler的實體。
LearnerHandler主要負責Leader和F/O之間的網絡通訊,包括數據同步,請求轉發和Proposal提議的投票等。Leader服務器保存了所有F/O的LearnerHandler。

12、ZooKeeper是否會自動進行日志清理?

如何進行日志清理?zk自己不會進行日志清理,需要運維人員進行日志清理。

13、談談你對ZooKeeper的理解?

Zookeeper 作為一個分布式的服務框架,主要用來解決分布式集群中應用系統的一致性問題。ZooKeeper提供的服務包括:分布式消息同步和協調機制、
服務器節點動態上下線、統一配置管理、負載均衡、集群管理等。
ZooKeeper提供基於類似於Linux文件系統的目錄節點樹方式的數據存儲,即分層命名空間。Zookeeper 並不是用來專門存儲數據的,
它的作用主要是用來維護和監控你存儲的數據的狀態變化,通過監控這些數據狀態的變化,從而可以達到基於數據的集群管理,ZooKeeper節點的數據上限是1MB。
我們可以認為Zookeeper=文件系統+通知機制,對於ZooKeeper的數據結構,每個子目錄項如 NameService 都被稱作為 znode,這個 znode 是被它所在的
路徑唯一標識,如 Server1 這個 znode 的標識為 /NameService/Server1;
znode 可以有子節點目錄,並且每個 znode 可以存儲數據,注意 EPHEMERAL 類型的目錄節點不能有子節點目錄(因為它是臨時節點);
znode 是有版本的,每個 znode 中存儲的數據可以有多個版本,也就是一個訪問路徑中可以存儲多份數據;
znode 可以是臨時節點,一旦創建這個 znode 的客戶端與服務器失去聯系,這個 znode 也將自動刪除,Zookeeper 的客戶端和服務器通信采用長連接方式,
每個客戶端和服務器通過心跳來保持連接,這個連接狀態稱為 session,如果 znode 是臨時節點,這個 session 失效,znode 也就刪除了;
znode 的目錄名可以自動編號,如 App1 已經存在,再創建的話,將會自動命名為 App2;
znode 可以被監控,包括這個目錄節點中存儲的數據的修改,子節點目錄的變化等,一旦變化可以通知設置監控的客戶端,這個是 Zookeeper 的核心特性,
Zookeeper 的很多功能都是基於這個特性實現的,后面在典型的應用場景中會有實例介紹。

14、ZooKeeper節點類型?

1)Znode有兩種類型:
短暫(ephemeral):客戶端和服務器端斷開連接后,創建的節點自己刪除。
持久(persistent):客戶端和服務器端斷開連接后,創建的節點不刪除。
2)Znode有四種形式的目錄節點(默認是persistent )
(1)持久化目錄節點(PERSISTENT) 客戶端與zookeeper斷開連接后,該節點依舊存在。
(2)持久化順序編號目錄節點(PERSISTENT_SEQUENTIAL) 客戶端與zookeeper斷開連接后,該節點依舊存在,
只是Zookeeper給該節點名稱進行順序編號。
(3)臨時目錄節點(EPHEMERAL) 客戶端與zookeeper斷開連接后,該節點被刪除。
(4)臨時順序編號目錄節點(EPHEMERAL_SEQUENTIAL)客戶端與zookeeper斷開連接后,該節點被刪除,只是Zookeeper給該節點名稱進行順序編號。

15、請說明ZooKeeper的通知機制?

ZooKeeper選擇了基於通知(notification)的機制,即:客戶端向ZooKeeper注冊需要接受通知的znode,通過znode設置監控點(watch)來接受通知。
監視點是一個單次觸發的操作,意即監視點會觸發一個通知。為了接收多個通知,客戶端必須在每次通知后設置一個新的監視點。在下圖闡述的情況下,
當節點/task發生變化時,客戶端會受到一個通知,並從ZooKeeper讀取一個新值。
ZK通知機制

16、ZooKeeper的監聽原理是什么?

在應用程序中,mian()方法首先會創建zkClient,創建zkClient的同時就會產生兩個進程,即Listener進程(監聽進程)和
connect進程(網絡連接/傳輸進程),當zkClient調用getChildren()等方法注冊監視器時,connect進程向ZooKeeper注冊監聽器,
注冊后的監聽器位於ZooKeeper的監聽器列表中,監聽器列表中記錄了zkClient的IP,端口號以及要監控的路徑,一旦目標文件發生變化,
ZooKeeper就會把這條消息發送給對應的zkClient的Listener()進程,Listener進程接收到后,就會執行process()方法,
在process()方法中針對發生的事件進行處理。
ZK監聽原理

17、請說明ZooKeeper使用到的各個端口的作用?

2888:Follower與Leader交換信息的端口。
3888:萬一集群中的Leader服務器掛了,需要一個端口來重新進行選舉,選出一個新的Leader,而這個端口就是用來執行選舉時服務器相互通信的端口。

18、ZooKeeper的部署方式有哪幾種?集群中的角色有哪些?集群最少需要幾台機器?

ZooKeeper的部署方式有單機模式和集群模式,集群中的角色有Leader和Follower,集群最少3(2N+1)台,根據選舉算法,應保證奇數。

19、ZooKeeper集群如果有3台機器,掛掉一台是否還能工作?掛掉兩台呢?

對於ZooKeeper集群,過半存活即可使用。

20、ZooKeeper使用的ZAB協議與Paxo算法的異同?

Paxos算法是分布式選舉算法,Zookeeper使用的 ZAB協議(Zookeeper原子廣播),兩者的異同如下:
1)相同之處:
比如都有一個Leader,用來協調N個Follower的運行;Leader要等待超半數的Follower做出正確反饋之后才進行提案;
二者都有一個值來代表Leader的周期。
2)不同之處:
ZAB用來構建高可用的分布式數據主備系統(Zookeeper),Paxos是用來構建分布式一致性狀態機系統。

21、請談談對ZooKeeper對事務性的支持?

ZooKeeper對於事務性的支持主要依賴於四個函數,zoo_create_op_init, zoo_delete_op_init, zoo_set_op_init以及zoo_check_op_init。
每一個函數都會在客戶端初始化一個operation,客戶端程序有義務保留這些operations。當准備好一個事務中的所有操作后,可以使用zoo_multi來提交所有的操作,
由zookeeper服務來保證這一系列操作的原子性。也就是說只要其中有一個操作失敗了,相當於此次提交的任何一個操作都沒有對服務端的數據造成影響。
Zoo_multi的返回值是第一個失敗操作的狀態信號。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM