[ Tutorial ] ZNode Types and How to Create, Read, Delete, and Write in ZooKeeper (Java)

Please click here to read about Create, Read, Delete, and Write znodes in ZooKeeper Client.

This is more like a continuation of my blog entry about creating, deleting, reading, and writing a znode in ZooKeeper Client. It will be mostly a few snippets of code. Although there are multiple ways, I will only present the simplest and easiest ways to create, read, delete and write znodes.

1. Creating a Znode

Java’s ZooKeeper create method takes in 4 parameters: Path [String], Data [byte array], Access Control List [ArrayList] and Mode [CreateMode]. Enclosed in the square brackets is the object type each parameter is.

As mentioned few times in my earlier blog entries, path always needs to start with the root znode ( / ). Remember, the path consists of the root znode and the name of the znode you want to create. For example, to create a znode called new_znode, you would write /new_znode for its path.

Data of a znode is stored in byte array. For the learning purposes, we will use the getBytes() method, which is a String method that converts String into byte array. Size of each znode is 1MB.

Access Control List (ACL) is stored in an ArrayList. We will use the final variable in the Ids class, which we will need to import. Furthermore, I will talk about the ACL more in detail. But for now, we will just stick with the Ids class.

Mode is the types of znodes I mentioned on my last blog entry: persistent, ephemeral, and sequential. We will be importing the CreateMode class to do this. There are four modes: Persistent (default), Persistent-Sequential, Ephemeral, and Ephemeral-Sequential. For now, we will use the default mode.

Example create method:

public void createZnode(String path, byte[] data) throws KeeperException, InterruptedException {
    zk.create(path, data, Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
}

create method throws KeeperException and InterruptedException. To anticipate the possibility of throwing either exceptions, surround the create method in a try...catch block.

Another example create method:

try {
    zk.create("/new_znode", "new znode".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
} catch(InterruptedException intrEx) {
    // do something to prevent the program from crashing
    System.out.println("\"new_znode\" already exists!");
} catch(KeeperException kpEx) {
    // do something to prevent the program from crashing
    System.out.println("\"new_znode\" already exists!");
}

2. Reading a Znode

To read a znode, we call the getData method. It takes 3 parameters: Path [String], watch [boolean], stat [Stat].

Again, it takes in the path to specify which znode you want to read. Watcher is relatively a simple concept, but I will talk more about this later. Stat contains a more in-depth information about the znode, such as number of children, when it was created, etc. Like the create method, this also throws InterruptedException and KeeperException.

Example getData method:

public byte[] readZnode(String path) throws KeeperException, InterruptedException {
    return zk.getData(path, true, zk.exists(path, true));
}

Another example getData method using try...catch block:

try {
    zk.getData("/new_znode", true, zk.exists("/new_znode", true));
} catch(InterruptedException intrEx) {
    // do something to prevent the program from crashing
    System.out.println("\"new_znode\" does not exist!");
} catch(KeeperException kpEx) {
    // do something to prevent the program from crashing
    System.out.println("\"new_znode\" does not exist!");
}

As you may have noticed, getData takes in a Watcher as part of the parameter. Watcher in a nutshell is a mechanism implemented in the ZooKeeper that keeps watch of the znode you specified; it serves to notify the client whether it has been deleted, its data has changed, or if there was any changes to that znode, it will notify the client. One thing to note is that once the Watcher notified the client of a watch_me znode (for example), a new Watcher needs to be set on that same znode again, or else it will not notify the client for the second time.

3. Writing (or Re-Writing) to a Znode

We use setData for writing to a znode. This method takes in 3 parameters: Path [String] as always, data [byte Array] that will overwrite the pre-existing data, and the version [int].

We have a new parameter (but fairly self-explanatory), which is version. Every time the znode gets updated, it makes sense to update its version. Because of this, if you try to pass in the integer value that is not a current version, it will throw a BadVersionException. Here is an example:

version

I have a znode named newznode and its dataVersion is 5. It would be a major hassle to go back to the code to update its version manually every time the client tries to update its data. Instead, we utilize the getVersion method (from Stat class) and pass that as an argument as follows:

public void writeZnode(String path, byte[] data) throws KeeperException, InterruptedException {
    Stat stat = zk.exists(path, true);
    zk.setData(path, data, stat.getVersion());
}

As usual, another example of setData method using the try...catch block:

try {
    Stat stat = zk.exists("/new_znode", true);
    zk.setData("/new_znode", "new data".getBytes(), stat.getVersion());
} catch(InterruptedException intrEx) {
    // do something to prevent the program from crashing
    System.out.println("\"new_znode\" does not exist!");
} catch(KeeperException kpEx) {
    // do something to prevent the program from crashing
    System.out.println("\"new_znode\" does not exist!");
}

Now, let’s try to pass in a random integer other than its version. Same scenario (except its version is now 6).

error version

Instead of passing in the stat.getVersion() like I should be, I’ll try to pass in a non-6 value, and you should expect to see this:

exception error

4. Deleting a Znode

To delete a znode, first we use the delete method (I’m sure you could have guessed that much), and it takes in 2 parameters: Path [String] and Version [int]. Again, because I have already went over these two parameters, I will move straight into the code. Version parameter in this method is exactly the same as the version from the setData method.

public void deleteZnode(String path) throws KeeperException, InterruptedException {
    Stat stat = zk.exists(path, true);
    zk.delete(path, stat.getVersion());
}

And finally, another (and the last) example using the try...catch block:

try {
    Stat stat = zk.exists("/new_znode", true);
    zk.delete("/new_znode", stat.getVersion());
} catch(InterruptedException intrEx) {
    // do something to prevent the program from crashing
    System.out.println("\"new_znode\" does not exist!");
} catch(KeeperException kpEx) {
    // do something to prevent the program from crashing
    System.out.println("\"new_znode\" does not exist!");
}

Thanks for reading. Happy zookeeping

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s