ZooKeeper:05---基礎語法(監視與通知:watch)

一、通過一個例子引出監視的概念

  • ZooKeeper通常以遠程服務的⽅式被訪問,如果每次訪問znode時,客戶端都需要獲得節點中的內容,這樣的代價就⾮常⼤。因爲這樣會導致更⾼的延遲,⽽且ZooKeeper需要做更多的操作

演示說明

  • 考慮下圖的例⼦,第⼆次調⽤getChildren/tasks返回了相同的值(⼀個空的集合),其實是沒有必要的

  • 這是⼀個常見的輪詢問題
  • 爲了替換客戶端的輪詢,我們選擇了基於通知(notification)的機制:
    • 客戶端向ZooKeeper註冊需要接收通知的znode,通過對znode設置監視點(watch)來接收通知
    • 如下圖所示,當節點/tasks發⽣變化時,客戶端會收到⼀個通知,並從ZooKeeper讀取⼀個新值

二、監視相關API

printwatches

  • 功能:開關,用來是否打印監視(watchers)信息
  • 格式:
printwatches on|off
  • 演示案例:
printwatches on

get

  • get有一個-w選項,用來在獲取路徑的數據時同時添加一個監視
  • 備註:要將printwatches設置爲on纔可以使用
  • 演示案例:
# 創建一個節點
create /latest_producer_id_block

printwatches on

# 添加監視
get -w /latest_producer_id_block

# 此處爲了演示監視,我們刪除該節點,會有信息輸出
delete /latest_producer_id_block

ls

  • 與get類似,ls頁有一個-w選項,用來在獲取路徑的數據時同時添加一個監視
  • 備註:要將printwatches設置爲on纔可以使用
  • 演示案例:
printwatches on

# 對/zookeeper添加監視
ls -w /zookeeper

addWatch

  • 功能:對一個節點添加監視
  • 格式:
addWatch [-m mode] path
  • 選項:
    • -m:可選的值有PERSISTENT,PERSISTENT_RECURSIVE。默認爲PERSISTENT_RECURSIVE

removewatches

  • 功能:刪除節點下的監視
  • 格式:
removewatches path [-c|-d|-a] [-l]
  • 演示案例:
create /test_node

# 添加監視
get -w /test_node

# 移除監視
removewatches /test_node

 

三、監視相關注意事項

監視點的單次觸發機制

  • 監視點是⼀個單次觸發的操作,意思爲監視點只觸發一次,觸發之後就消失了
  • 爲了接收多個通知,客戶端必須在每次通知後設置⼀個新的監視點

監視點更新前的變更

  • 因爲監視點是單次觸發操作,在單次觸發之後我們需要重新設置監視點。但是在“監視點被觸發”到“重新設置監視點”之間可能有其他新的數據加入到監視點中,因此我們需要解決這些問題
  • 場景如下,假設事件按以下順序發生:
    • 1.客戶端c1設置監視點來監控/tasks數據的變化
    • 2.客戶端c1連接後,向/tasks中添加了⼀個新的任務
    • 3.客戶端c1接收通知
    • 4.客戶端c1設置新的監視點,在設置完成前,第三個客戶端c3連接後, 向/tasks中添加了⼀個新的任務
  • 因爲客戶端c1在設置該監視點之前,該監視點已經被其他客戶端更新了因此c1在重新設置監視點之前需要讀取節點/tasks的狀態,通過在設置監視點前讀取ZooKeeper的狀態並更新狀態

監視變更的順序建議

  • 通知機制的⼀個重要保障是(是建議而不是強制要求):對同⼀個znode的操作,先向客戶端傳送通知,等所有的通知都結束之後再對該節點進⾏變更
  • 場景分析:
    • 客戶端對⼀個znode設置了監視點
    • 之後該znode發⽣了兩個連續更新(不是同時到達的)
    • 第⼀次更新後,第二次更新前,客戶端認爲節點發生改變了,立馬就去讀取數據
    • 第二次更新結束之後,客戶端丟失了這部分更新的數據
  • 我們認爲主要特性在於通知機制阻⽌了客戶端所觀察的更新順序。雖然ZooKeeper的狀態變化傳播給某些客戶端時更慢,但我們保障客戶端以全局的順序來觀察ZooKeeper的狀態

監視點的類型

  • ZooKeeper可以定義不同類型的通知,這依賴於設置監視點對應的通知類型
  • 客戶端可以設置多種監視點,如監控znode的數據變化、監控znode⼦節點的變化、監控znode的創建或刪除
  • 爲了設置監視點,可以使⽤任何API中的調⽤來讀取ZooKeeper的狀態,在調⽤這些API時,傳⼊⼀個watcher對象或使⽤默認的watcher。後面的“主從模式例子的實現”文章,及“處理狀態變更”中會以主從模式的例⼦來展開討論,我們將深⼊研究如何使⽤該機制

注意:誰來管理我的緩存

  • 如果不讓客戶端來管理其擁有的ZooKeeper數據的緩存,我們不得不讓ZooKeeper來管理這些應用程序的緩存。但是,這樣會導致ZooKeeper的設計更加複雜
  • 事實上,如果讓ZooKeeper管理緩存失效,可能會導致ZooKeeper在運⾏時,停滯在等待客戶端確認⼀個緩存失效的請求上,因爲在進⾏所有的寫操作前,需要確認所有的緩存數據是否已經失效
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章