Watch is a very important mechanism in zookeeper, which can monitor the change of nodes in zookeeper and inform the client. Below, we use code as an example to analyze how watch is implemented in zookeeper. Zookeeper in a total of three ways to achieve watch, respectively, GetData, exists and GetChildren, today we first look at the GetData () method:
1, GetData ()
Import Java.io.ioexception;import Org.apache.zookeeper.createmode;import org.apache.zookeeper.KeeperException; Import Org.apache.zookeeper.watchedevent;import Org.apache.zookeeper.watcher;import Org.apache.zookeeper.zookeeper;import Org.apache.zookeeper.zoodefs.ids;public class TestZooKeeperWatcher {public static void Main (string[] args) {ZooKeeper ZK = null;try {System.out.println ("..."); System.out.println ("..."); System.out.println ("..."); System.out.println ("..."); System.out.println ("Start connection Zookeeper ...");//Create a connection to the zookeeper server zkstring address = "192.168.1.226:2181"; int Sessiontimeout = 3000;zk = new ZooKeeper (address, sessiontimeout, new Watcher () {//monitor all triggered events public void process (Watchede Vent event) {if (event.gettype () = = NULL | | ". Equals (Event.gettype ())) {return;} System.out.println ("has triggered" + event.gettype () + "Event! ");}}); SYSTEM.OUT.PRINTLN ("Zookeeper Connection created successfully! "); Thread.CurrentThread (). Sleep (1000l); System.out.println ("..."); System.out.println ("..."); System.out.println ("..."); System.out.prIntln ("...");//create root node//path to/tmp_root_path//node content as string "I am the root directory/tmp_root_path"// The creation mode is CREATEMODE.PERSISTENTSYSTEM.OUT.PRINTLN ("Start creating root node/tmp_root_path ..."), Zk.create ("/tmp_root_path", "I am the root directory/ Tmp_root_path ". GetBytes (), Ids.open_acl_unsafe, createmode.persistent); SYSTEM.OUT.PRINTLN ("Root directory node/tmp_root_path created successfully! "); Thread.CurrentThread (). Sleep (1000l); System.out.println ("..."); System.out.println ("..."); System.out.println ("..."); System.out.println ("...");//Create First subdirectory node//path to/tmp_root_path/childpath1//node content as string "I am the first subdirectory/tmp_root_path/ ChildPath1 "//Create Mode is CREATEMODE.PERSISTENTSYSTEM.OUT.PRINTLN (" Start creating first subdirectory node/tmp_root_path/childpath1 ... "); Zk.create ("/tmp_root_path/childpath1", "I am the first subdirectory/tmp_root_path/childpath1". GetBytes (), Ids.open_acl_unsafe, Createmode.persistent); System.out.println ("First subdirectory node/tmp_root_path/childpath1 created successfully! "); Thread.CurrentThread (). Sleep (1000l); System.out.println ("..."); System.out.println ("..."); System.out.println ("..."); System.out.println ("..."); Thread.CurrentThread (). Sleep (1000l); System.Out.println ("..."); System.out.println ("..."); System.out.println ("..."); System.out.println ("...");//Create a second subdirectory node//path to/tmp_root_path/childpath2//node content as string "I am the second subdirectory/tmp_root_path/ ChildPath2 "//Create Mode is CREATEMODE.PERSISTENTSYSTEM.OUT.PRINTLN (" Start creating second subdirectory node/tmp_root_path/childpath2 ... "); Zk.create ("/tmp_root_path/childpath2", "I am the second subdirectory/tmp_root_path/childpath2". GetBytes (), Ids.open_acl_unsafe, Createmode.persistent); System.out.println ("Second subdirectory node/tmp_root_path/childpath2 created successfully! "); Thread.CurrentThread (). Sleep (1000l); System.out.println ("..."); System.out.println ("..."); System.out.println ("..."); System.out.println ("...");//Gets the second subdirectory node/tmp_root_path/childpath2 node data System.out.println ("Start getting second subdirectory node/tmp_root_ PATH/CHILDPATH2 node data ... "); System.out.println (New String (Zk.getdata ("/tmp_root_path/childpath2", True, null))); System.out.println ("Second subdirectory node/tmp_root_path/childpath2 node data gets successful! "); Thread.CurrentThread (). Sleep (1000l); System.out.println ("..."); System.out.println ("..."); System.out.println ("..."); System.out.println ("...");//Modify the first subdirectory node/tmp_root_path/childpath1 data System.out.println ("Start modifying the first subdirectory node/tmp_root_path/childpath1 data ...") ; Zk.setdata ("/tmp_root_path/childpath1", "I am the first subdirectory after modifying the data/tmp_root_path/childpath1". GetBytes (),-1); System.out.println ("Modify the first subdirectory node/TMP_ROOT_PATH/CHILDPATH1 data successfully! "); Thread.CurrentThread (). Sleep (1000l); System.out.println ("..."); System.out.println ("..."); System.out.println ("..."); System.out.println ("...");//Modify the second subdirectory node/tmp_root_path/childpath2 data System.out.println ("Start modifying the second subdirectory node/tmp_root_ Path/childpath2 data ... "); Zk.setdata ("/tmp_root_path/childpath2 "," I am the second subdirectory after modifying the data/tmp_root_path/childpath2 ". GetBytes (),-1); System.out.println ("Modify the second subdirectory node/TMP_ROOT_PATH/CHILDPATH2 data successfully! "); Thread.CurrentThread (). Sleep (1000l); System.out.println ("..."); System.out.println ("..."); System.out.println ("..."); System.out.println ("...");//delete the first subdirectory node System.out.println ("Start deleting the first subdirectory node/tmp_root_path/childpath1 ..."); zk.delete ("/tmp_root_path/childpath1",-1); System.out.println ("First subdirectory node/tmp_root_path/childpath1 deleted successfully! "); ThrEad.currentthread (). Sleep (1000l); System.out.println ("..."); System.out.println ("..."); System.out.println ("..."); System.out.println ("...");//delete the second subdirectory node System.out.println ("Start removing the second subdirectory node/tmp_root_path/childpath2 ..."); zk.delete ("/tmp_root_path/childpath2",-1); System.out.println ("Second subdirectory node/tmp_root_path/childpath2 deleted successfully! "); Thread.CurrentThread (). Sleep (1000l); System.out.println ("..."); System.out.println ("..."); System.out.println ("..."); System.out.println ("...");//delete root node System.out.println ("Start removing root node/tmp_root_path ...") zk.delete ("/tmp_root_path" ,-1); SYSTEM.OUT.PRINTLN ("Root directory node/tmp_root_path deleted successfully! "); Thread.CurrentThread (). Sleep (1000l); System.out.println ("..."); System.out.println ("..."); System.out.println ("..."); System.out.println ("..."); catch (IOException | keeperexception | Interruptedexception e) {//TODO auto-generated catch Blocke.printstacktrace ();} finally {//close connection if (ZK! = null) {try {zk. Close (); System.out.println ("Release Zookeeper connection succeeded! ");} catch (Interruptedexception e) {//TODO auto-generateD catch Blocke.printstacktrace ();}}}}
As we can see from the example above, we have created a root node,/tmp_root_path, and created two sub-nodes/tmp_root_path/childpath1 and/tmp_root_path/childpath2 below the root node. And we add a piece of code, get the second subdirectory node/tmp_root_path/childpath2 node data call ZK's GetData () method, the second parameter is set to True, that is, to monitor the second child node/tmp_root_path/ ChildPath2, the execution results are as follows:
............ Start Connecting zookeeper ... Zookeeper Connection created successfully! The None event has been triggered! ............ Start creating root directory Node/tmp_root_path ... Root node/tmp_root_path created successfully! ............ Start creating the first subdirectory node/tmp_root_path/childpath1 ... The first subdirectory node/tmp_root_path/childpath1 created successfully! ........................ Start creating a second subdirectory node/tmp_root_path/childpath2 ... The second subdirectory node/tmp_root_path/childpath2 created successfully! ............ Start getting Second subdirectory node/tmp_root_path/childpath2 node data ... I am the second subdirectory/tmp_root_path/childpath2 Second subdirectory node/tmp_root_path/childpath2 node data gets successful! ............ Start modifying the first subdirectory node/tmp_root_path/childpath1 data ... Modify the first subdirectory node/TMP_ROOT_PATH/CHILDPATH1 data successfully! ............ Start modifying the second subdirectory node/tmp_root_path/childpath2 data ... The Nodedatachanged event has been triggered! Modify the second subdirectory node/TMP_ROOT_PATH/CHILDPATH2 data successfully! ............ Start Delete First subdirectory node/tmp_root_path/childpath1 ... The first subdirectory node/tmp_root_path/childpath1 deleted successfully! ............ Start removing the second subdirectory node/tmp_root_path/childpath2 ... The second subdirectory node/tmp_root_path/childpath2 deleted successfully! ............ Start Delete root node/tmp_root_path ... Root node/tmp_root_path deleted successfully! ............ Release Zookeeper connection Successful!
You can find that when you modify the second child node/tmp_root_path/childpath2 data, the Nodedatachanged event is triggered, and the corresponding modification of the first subdirectory node/tmp_root_path/childpath1 the data, The event is not triggered, and the second child node/tmp_root_path/childpath2 is not triggered when it is deleted!
And when we block to modify the second child node/tmp_root_path/childpath2 data related code, the masked part and execution result are as follows:
Modify the second subdirectory node/tmp_root_path/childpath2 data//system.out.println ("Start modifying the second subdirectory node/tmp_root_path/childpath2 data ...");// Zk.setdata ("/tmp_root_path/childpath2",//"I am the second subdirectory after modifying the data/tmp_root_path/childpath2". GetBytes (),-1);// System.out.println ("Modify the second subdirectory node/TMP_ROOT_PATH/CHILDPATH2 data successfully! ");////thread.currentthread (). Sleep (1000l);////system.out.println (" ... ");//system.out.println (" ... ");// System.out.println ("...");//system.out.println ("...");
... Start Connecting zookeeper ... Zookeeper Connection created successfully! The None event has been triggered! ............ Start creating root directory Node/tmp_root_path ... Root node/tmp_root_path created successfully! ............ Start creating the first subdirectory node/tmp_root_path/childpath1 ... The first subdirectory node/tmp_root_path/childpath1 created successfully! ........................ Start creating a second subdirectory node/tmp_root_path/childpath2 ... The second subdirectory node/tmp_root_path/childpath2 created successfully! ............ Start getting Second subdirectory node/tmp_root_path/childpath2 node data ... I am the second subdirectory/tmp_root_path/childpath2 Second subdirectory node/tmp_root_path/childpath2 node data gets successful! ............ Start modifying the first subdirectory node/tmp_root_path/childpath1 data ... Modify the first subdirectory node/TMP_ROOT_PATH/CHILDPATH1 data successfully! ............ Start Delete First subdirectory node/tmp_root_path/childpath1 ... The first subdirectory node/tmp_root_path/childpath1 deleted successfully! ............ Start removing the second subdirectory node/tmp_root_path/childpath2 ... The nodedeleted event has been triggered! The second subdirectory node/tmp_root_path/childpath2 deleted successfully! ............ Start Delete root node/tmp_root_path ... Root node/tmp_root_path deleted successfully! ............ Release Zookeeper connection Successful!
The execution result is obvious, the Nodedatachanged event is triggered when the second child node/tmp_root_path/childpath2 is deleted, but the first child node is modified and the first child node is deleted without triggering!
Let's make another change and modify the second child node/tmp_root_path/childpath2 two times, so what's the result of the execution? The added code and execution results are as follows:
Second modification of the second subdirectory node/tmp_root_path/childpath2 data System.out.println ("Start the second time modifying the second subdirectory node/tmp_root_path/childpath2 data ..."); Zk.setdata ("/tmp_root_path/childpath2", "I am the second subdirectory after the second modification of the data/tmp_root_path/childpath2". GetBytes (),-1); SYSTEM.OUT.PRINTLN ("Second modification of the second subdirectory node/tmp_root_path/childpath2 data succeeded! "); Thread.CurrentThread (). Sleep (1000l); System.out.println ("..."); System.out.println ("..."); System.out.println ("..."); System.out.println ("...");
............ Start Connecting zookeeper ... Zookeeper Connection created successfully! The None event has been triggered! ............ Start creating root directory Node/tmp_root_path ... Root node/tmp_root_path created successfully! ............ Start creating the first subdirectory node/tmp_root_path/childpath1 ... The first subdirectory node/tmp_root_path/childpath1 created successfully! ........................ Start creating a second subdirectory node/tmp_root_path/childpath2 ... The second subdirectory node/tmp_root_path/childpath2 created successfully! ............ Start getting Second subdirectory node/tmp_root_path/childpath2 node data ... I am the second subdirectory/tmp_root_path/childpath2 Second subdirectory node/tmp_root_path/childpath2 node data gets successful! ............ Start modifying the first subdirectory node/tmp_root_path/childpath1 data ... Modify the first subdirectory node/TMP_ROOT_PATH/CHILDPATH1 data successfully! ............ Start modifying the second subdirectory node/tmp_root_path/childpath2 data ... The Nodedatachanged event has been triggered! Modify the second subdirectory node/TMP_ROOT_PATH/CHILDPATH2 data successfully! ............ Start the second time modifying the second subdirectory node/tmp_root_path/childpath2 data ... Second modification of the second subdirectory node/TMP_ROOT_PATH/CHILDPATH2 data Success! ............ Start Delete First subdirectory node/tmp_root_path/childpath1 ... The first subdirectory node/tmp_root_path/childpath1 deleted successfully! ............ Start removing the second subdirectory node/tmp_root_path/childpath2 ... The second subdirectory node/tmp_root_path/childpath2 deleted successfully! ............ Start Delete root node/tmp_root_path ... Root node/tmp_root_path deleted successfully! ............ Release Zookeeper connection Successful!
The Nodedatachanged event is triggered only when the second child node is modified/TMP_ROOT_PATH/CHILDPATH2 data for the first time, and the second modification and deletion are not triggered!
And when we get the second child node/tmp_root_path/childpath2 data before the second time, and watch set to true, then two times to the second child node/tmp_root_path/ ChildPath2 data changes will trigger the Nodedatachanged event, and when the root node data is obtained, it is only the monitoring root directory, its subdirectory changes will not trigger the Nodedatachanged event, the reader can try it yourself!
Conclusion:
The GetData () method only monitors the data changes of the corresponding nodes, whether it is data modification or deletion! To be monitored each time the corresponding node changes, you must first call the GetData () method to get the data again!
ZooKeeper Watch Java API Analysis GetData