zookeeper之 watch機制(三)


zk作為一款成熟的分布式協調框架,訂閱-發布功能是很重要的一個。所謂訂閱發布功能,其實說白了就是觀察者模式。觀察者會訂閱一些感興趣的主題,然后這些主題一旦變化了,就會自動通知到這些觀察者。

zk的訂閱發布也就是watch機制,是一個輕量級的設計。因為它采用了一種推拉結合的模式。一旦服務端感知主題變了,那么只會發送一個事件類型和節點信息給關注的客戶端,而不會包括具體的變更內容,所以事件本身是輕量級的,這就是所謂的“推”部分。然后,收到變更通知的客戶端需要自己去拉變更的數據,這就是“拉”部分。
watch機制

一、目標是誰?

 zode  /path (節點操作來觸發watch)

  1、創建

  2、修改

  3、刪除

  4、查詢

  5、是否存在

二、使用

     可以注冊watcher的方法:getData、exists、getChildren。

 public static void main(String[] args) throws KeeperException {
        try {
//            連接
            ZooKeeper connect = zookeeperConnection.connect("192.168.44.5:2181");
//            注冊watch
            connect.getData("/alex",new GetMyWatch(),connect.exists("/alex",false));
//            因為是main方法,使用此方法保證線程不被停止
            System.in.read();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 自定義監聽器
     */
    private static  class GetMyWatch implements Watcher{

        @Override
        public void process(WatchedEvent watchedEvent) {
            System.out.println(watchedEvent.getState());
            System.out.println("getData 數據回調");
        }
    }

 

    可以觸發watcher的方法:create、delete、setData。連接斷開的情況下觸發的watcher會丟失。

修改此節點,觀察watch是否被調用

 可以觀察到watch 被調用了,但是在這里有一個注意的地方,watch是一次性的,只會被調用一次,你在后面再次修改節點,watch是不會被調用的

 

zookeeper Watcher機制的特點

1、一次性的觸發器(one-time trigger)

當數據改變的時候,Watch事件會產生並且被發送到客戶端中。但是客戶端只會收到一次這樣的通知,如果以后這個數據再次發生改變的時候,之前設置Watch的客戶端將不會再次收到改變的通知,因為Watch機制規定了它是一個一次性的觸發器。 當設置監視的數據發生改變時,該監視事件會被發送到客戶端。例如,如果客戶端調用了 getData("/znode1", true) 並且稍后 /znode1 節點上的數據發生了改變或者被刪除了,客戶端將會獲取到 /znode1 發生變化的監視事件,而如果 /znode1 再一次發生了變化,除非客戶端再次對 /znode1 設置監視,否則客戶端不會收到事件通知。

2、發送給客戶端(Sent to the client)

這個表明了Watch的通知事件是從服務器發送給客戶端的,是異步的,這就表明不同的客戶端收到的Watch的時間可能不同,但是ZooKeeper有保證:當一個客戶端在看到Watch事件之前是不會看到結點數據的變化的。例如:A=3,此時在上面設置了一次Watch,如果A突然變成4了,那么客戶端會先收到Watch事件的通知,然后才會看到A=4。 Zookeeper 客戶端和服務端是通過 Socket 進行通信的,由於網絡存在故障,所以監視事件很有可能不會成功地到達客戶端,監視事件是異步發送至監視者的,Zookeeper 本身提供了保序性(ordering guarantee):即客戶端只有首先看到了監視事件后,才會感知到它所設置監視的 znode 發生了變化(a client will never see a change for which it has set a watch until it first sees the watch event). 網絡延遲或者其他因素可能導致不同的客戶端在不同的時刻感知某一監視事件,但是不同的客戶端所看到的一切具有一致的順序。

3、被設置Watch的數據(The data for which the watch was set)

這意味着 znode 節點本身具有不同的改變方式。你也可以想象 Zookeeper 維護了兩條監視鏈表: 數據監視和子節點監視(data watches and child watches) 。 getData() and exists() 設置數據監視,getChildren() 設置子節點監視。 或者,你也可以想象 Zookeeper 設置的不同監視返回不同的數據,getData() 和 exists() 返回 znode 節點的相關信息,而 getChildren() 返回子節點列表。 因此, setData() 會觸發設置在某一節點上所設置的數據監視(假定數據設置成功),而一次成功的 create() 操作則會出發當前節點上所設置的數據監視以及父節點的子節點監視。一次成功的 delete() 操作將會觸發當前節點的數據監視和子節點監視事件,同時也會觸發該節點父節點的child watch。

 


免責聲明!

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



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