【Zookeeper讀書筆記-1】系統模型

ZK模型分成數據模型,節點特性,版本,Watcher,ACL五個部分。

 

1 數據模型

樹形結構:每個節點成爲ZNode,是數據的最小單元,每個節點可以存放數據或者是子節點。

事務ID:ZXID,每次對服務器狀態進行操作,就會分配全局的事務ID

2 節點類型

根據節點生命週期長短分成持久節點,臨時節點,順序節點

持久節點:一直存在服務端,直到手動刪除。

臨時節點:生命週期是客戶端的會話失效週期,不是TCP斷開連接。臨時節點只能作爲葉子節點,不能基於臨時節點創建子節點。

順序節點:節點可能還表現爲順序特性,即節點在父節點列表中是否標記創建順序。

3 狀態信息

節點信息包含節點數據內容以及狀態信息。

czxid:reated ZXID,表示該節點被創建時的事務ID。
mzxid:Modified ZXID,表示該節點最後一次被更新時的事務ID。
ctime:表示節點被創建的時間。
mtime:表示該節點最後一次被更新時的時間。
version:數據節點的版本號。節點被創建後,被更新過的次數,即使更新的內容與原內容相同,也視爲一次更新。
cversion:子節點的版本號。
aversion:節點的ACL版本號。
ephemeralOwner:創建該臨時節點的會話的SessionID。如果該節點爲持久節點,那麼這個屬性值爲0。
dataLength:數據內容的長度。
numChildren:當前節點的子節點個數。
pzxid:表示該節點的子節點列表最後一次被修改時的事務ID。只有子節點列表變更了纔會變更pzxid,子節點內容變更不會影響pzxid。

4 Watcher數據變更通知

一對多的發佈訂閱模式,客戶端向服務端註冊watcher,監聽某一特定主題的對象,當主題對象自身發生變化時,會通知所有的訂閱者。

4.1 watcher基礎

Watcher機制包括:客戶端,客戶端WatcherManager,服務端。

客戶端向服務端註冊watcher同時會把watcher對象存入WatcherManager中,當服務端觸發Watcher事件後,會向服務端發送通知,服務端從WatcherManager中取出對應的Watcher對象,執行回調邏輯。

Watcher特性包含:

  1. 註冊一次性:服務端或者客戶端的watcher一旦被觸發,就會被刪除。如果需要監聽,就要反覆註冊。否則一些更新比較頻繁的節點,每次變動都要不斷地將通知反饋給客戶端,對與網絡以及服務端性能影響很大。
  2. 客戶端Watcher回調是串行同步的,保證了每個wathcer的順序。
  3. 輕量級watcher。WatchedEvent是Watcher機制的最小通知單元,只包含了通知狀態,事件類型,節點路徑,不給出具體的變化內容,需要客戶端自己去相應節點獲取變化的內容,保證了客戶端服務端交互的數據量級。

4.2 Watcher事件

注意:

NodeDataChanged:與dataVersion一致,即使變更內容前後一樣,也會觸發此事件。

NodeChildrenChanged:所關注的節點的子節點列表有變化。這裏說的變化是指子節點的個數和組成,具體到子節點內容的變化是不會通知的。

4.3 process回調方法

WatchEvent包含三個屬性:事件狀態keeperstate,事件類型eventType,節點路徑path。

abstract public void process(WatchedEvent event);

/**
 *  A WatchedEvent represents a change on the ZooKeeper that a Watcher
 *  is able to respond to.  The WatchedEvent includes exactly what happened,
 *  the current state of the ZooKeeper, and the path of the znode that
 *  was involved in the event.
 */
@InterfaceAudience.Public
public class WatchedEvent {
    final private KeeperState keeperState;
    final private EventType eventType;
    private String path;
}

4.4 Watcher工作機制

watcher註冊機制包括:客戶端註冊Watcher,服務端處理Watcher,客戶端回調Watcher。

4.4.1 客戶端註冊Watcher

1. 創建zk客戶端對象實例時註冊watcher,這個 Watcher 將作爲整個 ZooKeeper 會話期間的默認 Watcher,它會一直被保存在客戶端 ZKWatchManager 的 defaultWatcher 裏面。(getData, getChildren, exists方法中也可以註冊watcher)。

2. 例如getData註冊Watcher後,客戶端會向當前的request標記,設置爲“使用watcher監聽”,同時封裝WatcherRegistration對象用於暫時保存數據節點路徑和wathcer對應關係。

3. WatchRegistration被封裝成Packet對象,放入發送隊列等待客戶端發送。客戶端沒有把Watcher對象發送給服務端,只是將request與requestHeader兩個屬性序列化傳輸,否則服務端就容易出現內存緊張甚至溢出的危險。

4. ZKWatcherManager.dataWatches是Map<String, Set<Watcher>>保存數據節點路徑與Watcher對象關係。

4.4.2 服務端處理Watcher

對於註冊 Watcher 請求,FinalRequestProcessor 的 ProcessRequest 方法會判斷當前請求是否需要註冊 Watcher,如果爲 true,就會將當前的 ServerCnxn 對象和數據節點路徑傳入 getData 方法中去。ServerCnxn 是一個 ZooKeeper 客戶端和服務器之間的連接接口,代表了一個客戶端和服務器的連接,我們後面講到的 process 回調方法,實際上也是從這裏回調的,所以可以把 ServerCnxn 看作是一個 Watcher 對象。數據節點的節點路徑和 ServerCnxn 最終會被存儲在 WatchManager 的 watchTable 和 watch2Paths 中。
WatchManager 負責 Watcher 事件的觸發,它是一個統稱,在服務端 DataTree 會託管兩個 WatchManager,分別是watchTable和 watch2Paths,分別對應數據變更 Watcher 和節點變更 Watcher。

當DataTree中節點數據內容或版本發生變化或節點變更時,會調用相應方法去觸發 WatchManager 的 triggerWatch 方法,該方法返回 ZNODE 的信息,自此進入到回調本地 process 的序列。

4.4.3 客戶端回調Watcher

SendThread的response()方法負責接收這個客戶端事件通知。首先會對replyHeader中xid進行判斷,如果是-1,則說明是一個通知類型的響應。作以下處理:

1.反序列化:ZooKeeper客戶端接到請求後,首先將字節流轉換成WatcherEvent對象。

2.處理chrootPath:如果客戶端設置了chrootPath屬性,那麼需要對服務端傳過來的完整的節點路徑進行chrootPath處理,生成客戶端的一個相對節點路徑。

3.還原WatchedEvent:將WatcherEvent對象轉換成WatchedEvent。

4.回調Watcher:將WatchedEvent對象交給EventThread線程,在下一個輪詢週期中進行Watcher回調。

5 ACL保障數據安全

用於對節點的權限進行控制,一個有效的ACL信息包含:權限模式(Scheme),授權對象(ID),權限(Permission),即"scheme:ID:permission"。

 

參考:

https://www.cnblogs.com/shamo89/p/9787176.html

圖比較詳細

https://www.cnblogs.com/ZhuChangwu/p/11593642.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章