Zookeeper Barriers Example | Double Barrier in ZooKeeper

Boost your career with Free Big Data Courses!!

In our last ZooKeeper tutorial, we discussed ZooKeeper Queues. Today, in this Zookeeper article, we will see the detailed description of Zookeeper Barriers along with an example to understand it well.

Basically, in order to synchronize the computations in Zookeeper, we use primitives known as a Barriers in ZooKeeper. However, there is so much to learn about Zookeeper Barriers.

So, let’s begin with ZooKeeper Barriers.

What are ZooKeeper Barriers?

A primitive which enables a group of processes, in order to synchronize the beginning as well as the end of a computation, is what we call a barrier in ZooKeeper. 

Generally, the concept of implementing it is, to have a barrier node for individual process nodes which serves the purpose of being a parent. Now, let’s assume there is a ZooKeeper barrier node “/b11”. So, every process “p” creates a node “/b11/p”. 

So, joined processes can start the computation, as soon as enough processes have created their corresponding nodes.

Example of ZooKeeper Barriers
Though each process instantiates a Barrier object, in this example and its constructor takes as parameters:

  1. ZooKeeper server’s address(e.g., “zoo1.foo.com:2181”).
  2. Barrier node’s path on ZooKeeper (e.g., “/b11”).
  3. Size of the group of processes.

As a process Barrier’s constructor passes Zookeeper server’s address to the constructor of the parent class.

Afterward, a ZooKeeper instance is created by a parent class if no instance exists. Then Barrier’s constructor do creates a barrier node on a ZooKeeper. However, it is the parent node of all process nodes, which we also call a root.

/**
        * Barrier constructor
        *
        * @param address
        * @param root
        * @param size
        */
       Barrier(String address, String root, int size) {
           super(address);
           this.root = root;
           this.size = size;
           // Create barrier node
           if (zk != null) {
               try {
                   Stat s = zk.exists(root, false);
                   if (s == null) {
                       zk.create(root, new byte[0], Ids.OPEN_ACL_UNSAFE,
                               CreateMode.PERSISTENT);
                   }
               } catch (KeeperException e) {
                   System.out
                           .println("Keeper exception when instantiating queue: "
                                  + e.toString());
               } catch (InterruptedException e) {
                   System.out.println("Interrupted exception");
               }
           }
           // My node name
           try {
               name = new String(InetAddress.getLocalHost().getCanonicalHostName().toString());
           } catch (UnknownHostException e) {
               System.out.println(e.toString());
           }
       }

Further, a process calls enter(), to enter the barrier. Moreover, in order to form the node name, the process creates a node under the root to represent it, by using its hostname. Afterward, until enough processes have entered the barrier, it waits.

A process does it by checking the number of children the root node has with “getChildren()”, and waiting for notifications in the case it does not have enough.

However, a process has to set a watch, to receive a notification while there is a change to the root node, and also it does through the call to “getChildren()”. Though, we have that “getChildren()” has two parameters in the code.

  • Here, the first one states the node to read from.
  • Another one that enables the process to set a watch, which is a boolean flag.

Though, in the code the flag is true.

/**
  * Join barrier
  *
  * @return
  * @throws KeeperException
  * @throws InterruptedException
  */
 boolean enter() throws KeeperException, InterruptedException{
     zk.create(root + "/" + name, new byte[0], Ids.OPEN_ACL_UNSAFE,
             CreateMode.EPHEMERAL_SEQUENTIAL);
     while (true) {
         synchronized (mutex) {
             List<String> list = zk.getChildren(root, true);
             if (list.size() < size) {
                 mutex.wait();
             } else {
                 return true;
             }
         }
     }
 }

However, a process calls leave() to leave the barrier, once the computation is finished. At very first, it deletes its corresponding node, after that it gets the children of the root node.

Though it waits for a notification if there is at least one child. Also, it checks once more whether the root node has any children, upon reception of a notification.

    /**
     * Wait until all reach barrier
     *
     * @return
     * @throws KeeperException
     * @throws InterruptedException
     */
    boolean leave() throws KeeperException, InterruptedException{
        zk.delete(root + "/" + name, 0);
        while (true) {
            synchronized (mutex) {
                List<String> list = zk.getChildren(root, true);
                    if (list.size() > 0) {
                        mutex.wait();
                    } else {
                        return true;
                    }
                }
            }
    }
}

Double Barriers

Basically, to synchronize the beginning and the end of a computation, Double barriers enable clients.

However, all the processes start their computation and leave the barrier once they have finished, at the time when enough processes have joined the barrier. So, how to use a ZooKeeper node as a barrier is actually shown by this recipe.

Although, in this recipe, the pseudo-code represents the barrier node as b. On entry only, every client process p registers with the barrier node. And, when it is ready to leave it unregisters.

So, via the Enter procedure below, a node registers with the barrier node. That says until x client process register before proceeding with the computation it waits.

S.no. EnterLeave
1Create a name n = b+“/”+pL = getChildren(b, false)
2Set watch: exists(b + ‘‘/ready’’, true)if no children, exit
3Create child: create( n, EPHEMERAL)if p is only process node in L, delete(n) and exit
4L = getChildren(b, false)And, if somehow the p is the lowest process node in L, so do wait on highest process node in P
5if fewer children in L than  x, wait for watch eventelse delete(n) if still exists and wait on lowest process node in L
6else create(b + ‘‘/ready’’, REGULAR)goto 1

All the processes watch on a ready node and further it does create an ephemeral node as a child of the barrier node, on entering. Furthermore, each process enters the barrier and waits for the ready node to appear at line 5, but not the last.

And the last process which creates the xth node will see x nodes in the list of children. Then that creates the ready node, waking up the other processes. Although, note that waiting is efficient because only when it is time to exit, waiting for processes wake up.

Whereas, because we are watching for process nodes to go away, we can’t use a flag such as ready, on exit.

Moreover, processes that fail after the barrier has been entered do not prevent correct processes from finishing, by using ephemeral nodes. In addition, they need to delete their process nodes and wait for all other processes to do the same, at the time processes are ready to leave.

However, at the time when there are no process nodes left as children of b, Processes exit. Though, we can use the lowest process node as the ready flag, as an efficiency.

Most importantly, on each node deletion except for the last node, only a single process wakes up, also that wakes up everyone while it is removed.

So, this was all in ZooKeeper Barriers. Hope you like our explanation.

Conclusion: Zookeeper Barriers

Hence, we have seen Zookeeper Barriers in detail. In this, we discussed the ZooKeeper Double Barrier and ZooKeeper Barrier example. However, if any doubt occurs regarding, feel free to ask in the comment section. We are happy to help!

You give me 15 seconds I promise you best tutorials
Please share your happy experience on Google

follow dataflair on YouTube

1 Response

  1. Aman jain says:

    What is basic difference between barrier and Double barrier

Leave a Reply

Your email address will not be published. Required fields are marked *