Wednesday, August 9, 2017

We continue discussing the ZooKeeper. It incorporates elements from group messaging, shared registers and distributed lock services in a replicated, centralized service. It provides a interface that guarantees wait-free property and FIFO execution of requests from each client.  Requests across all clients are also linearized. In order to do this, it implements a leader based atomic broadcast protocol called Zab. Zab is only used to linerarize writes. Reads can happen in any order and ZooKeeper services them at the local server.
Caching is also used to improve performance. The id of the leader is useful to cache because it is frequently required and avoids asking other servers.  ZooKeeper uses a watch mechanism to enable clients to cache data without managing the client cache directly.  With this mechanism, a client can watch for an update to a given data object, and receive notification about update.  Chubby on the other hand centrally updates the data and blocks updates to invalidate the caches of all clients caching the data being changed. Leases are used to prevent a client from blocking the update indefinitely but leases only affect slow or faulty clients whereas ZooKeeper avoids this problem altogether.
ZooKeeper therefore demonstrates the following :
1) A co-ordination kernel  which provides a wait free co-ordination service with relaxed consistency guarantees to be used in distributed systems
2) A set of higher level co-ordination primitives  that are easy to be used in distributed computing.
3) Experience with co-ordination in a variety of distributed systems.
In ZooKeeper terminology, a client denotes the user of a ZooKeeper service, a server denotes a process providing ZooKeeper service, and znode denotes an in-memory data node which is organized in a hierarchical namespace as the data tree.
#codingexercise
Print Level order traversal of a tree
Void PrintSpiral (Node root)
{
bool change = false;
for (int i = 1; i < height (root); i++)
{
      PrintGivenLevel (root, i, change);
       change = !change;
}
}
void PrintGivenLevel(Node root, int level, bool direction)
{
   if (root == null) return;
   if (level ==1) print(root.data);
   else if level > 1{
       if (direction){
            PrintGivenLevel(root.left, level - 1, direction);
            PrintGivenLevel(root.right, level -1, direction);
       }else{
            PrintGivenLevel(root.right, level-1, direction);

            PrintGivenLevel(root.left, level -1, direction);
       }
    }
}

Instead of the recursive option above, we can also enumerate each level with the help of a queue and reverse only alternate levels. Here we can serialize the nodes with level demarcators and then switch alternatively in one pass.

No comments:

Post a Comment