面試官問:ZooKeeper 有幾種節(jié)點類型?別回答 4 種啦
本文轉(zhuǎn)載自微信公眾號「HelloGitHub」,作者HelloGitHub。轉(zhuǎn)載本文請聯(lián)系HelloGitHub公眾號。
一、關(guān)于 ZK 的節(jié)點類型
大家如果刷過 ZK 相關(guān)面試題的話,就一定會刷到過 “ZK 有幾種節(jié)點類型?”,大家通常背書的答案的話是:4 種!但其實 ZK (3.6.2)服務(wù)端支持 7 種節(jié)點類型,分別是:
- 持久
- 持久順序
- 臨時
- 臨時順序
- 容器
- 持久 TTL
- 持久順序 TTL
這 7 種類型之前的文章中也有提到過,但是并沒有展開講。這次更新的單篇想要把這 7 種類型的節(jié)點,認認真真的講一遍!Let's GO
二、簡單介紹
2.1 持久、臨時
持久不用我多說,是用的最多的一種類型,也是默認的節(jié)點類型,臨時節(jié)點相較于持久節(jié)點來說,就是它會隨著客戶端會話結(jié)束而被刪除,通常可以用在一些特定的場景,例如分布式鎖釋放,健康檢查等。
2.2 持久順序、臨時順序
這兩種我放在一起介紹,因為他們相對于上面兩種的特性就是 ZK 會自動在這兩種節(jié)點之后增加一個數(shù)字的后綴,而路徑 + 數(shù)字后綴是能保證唯一的,這數(shù)字后綴的應(yīng)用場景可以實現(xiàn)諸如分布式隊列,分布式公平鎖等。
2.3 容器
容器節(jié)點是 3.5 以后新增的節(jié)點類型,只要在調(diào)用 create 方法時,指定 CreateMode 為 CONTAINER 即可創(chuàng)建容器的節(jié)點類型,容器節(jié)點的表現(xiàn)形式和持久節(jié)點是一樣的,但是區(qū)別是 ZK 服務(wù)端啟動后,會有一個單獨的線程去掃描,所有的容器節(jié)點,當發(fā)現(xiàn)容器節(jié)點的子節(jié)點數(shù)量為 0 時,會自動刪除該節(jié)點,除此之外和持久節(jié)點沒有區(qū)別,官方注釋給出的使用場景是 Container nodes are special purpose nodes useful for recipes such as leader, lock, etc. 說可以用在 leader 或者鎖的場景中。
2.4 持久 TTL、持久順序 TTL
關(guān)于持久和順序這兩個關(guān)鍵字,不用我再解釋了,這兩種類型的節(jié)點重點是后面的 TTL,TTL 是 time to live 的縮寫,指帶有存活時間,簡單來說就是當該節(jié)點下面沒有子節(jié)點的話,超過了 TTL 指定時間后就會被自動刪除,特性跟上面的容器節(jié)點很像,只是容器節(jié)點沒有超時時間而已,但是 TTL 啟用是需要額外的配置(這個之前也有提過)配置是 zookeeper.extendedTypesEnabled 需要配置成 true,否則的話創(chuàng)建 TTL 時會收到 Unimplemented 的報錯
三、原理介紹
單純的持久和臨時節(jié)點我就不介紹了,之前的系列文章有講
3.1 順序關(guān)鍵字
客戶端創(chuàng)建一個順序節(jié)點的時候,服務(wù)端得知當前節(jié)點是順序節(jié)點的時候會自動給路徑加上后綴,后綴就是父節(jié)點的 cversion,代表創(chuàng)建子節(jié)點的個數(shù)
- if (createMode.isSequential()) {
- path = path + String.format(Locale.ENGLISH, "%010d", parentCVersion);
- }
就是這么簡單~
3.2 容器、TTL 關(guān)鍵字
這兩種其實可以放在一起講,服務(wù)端在啟動的時候會額外啟動一個定時任務(wù)線程,會定期的掃描所有的容器和 TTL 的節(jié)點,逐一判斷子節(jié)點的數(shù)量以及一些相關(guān)配置,來決定是否刪除,首先整個邏輯是在 ContainerManager 中,定時任務(wù)是由 TimeTask 實現(xiàn)的,相關(guān)的配置有
配置項 | 默認值 | 說明 |
---|---|---|
znode.container.checkIntervalMs | 60000(毫秒) | 定時任務(wù)檢查的間隔 |
znode.container.maxPerMinute | 10000 | 和上面的參數(shù)聯(lián)合成為最小的檢查間隔,每個節(jié)點間隔必須差 (60000 / 10000)毫秒(默認 6 毫秒)以上 |
znode.container.maxNeverUsedIntervalMs | 0 | 如果配置不為 0 的話,當容器和 TTL 節(jié)點最后一次更新的時間和當前時間戳的差超過這個值的話,也會被刪除 |
四、小結(jié)
- 持久關(guān)鍵字:客戶端不主動刪除的話,節(jié)點數(shù)據(jù)會一直存在
- 臨時關(guān)鍵字:客戶端連接斷開后,節(jié)點數(shù)據(jù)會被一起刪除
- 順序關(guān)鍵字:服務(wù)端會自動為該節(jié)點加數(shù)字后綴
- 容器:服務(wù)端會定期掃描這些節(jié)點,當該節(jié)點下面沒有子節(jié)點時(或其他條件時)服務(wù)端會自動刪除節(jié)點
- TTL:需要額外配置才能啟用,基本和容器相同,當超過 TTL 時間節(jié)點下面都沒有再創(chuàng)建子節(jié)點時會被刪除,但是當創(chuàng)建子節(jié)點會重置該超時時間