Exploring Apache ZooKeeper :: Part-1
Bhaskar S | 05/17/2014 |
Overview
Apache ZooKeeper is a robust, reliable, and resilient open-source coordination service that can be leveraged by distributed applications.
ZooKeeper exposes a simple set of primitives which can be leveraged to build highly reliable cluster-aware distributed applications with the following capabilities:
Configuration Management :: Store and manage configuration information in ZooKeeper
Group Membership :: Maintain a current list of all the active processes (members) for a distributed application in ZooKeeper
Leader Election :: Maintain a single Master (or Leader) for making critical decisions in a distributed application using ZooKeeper
Naming Service :: Maintain a map of names to values for the distributed application in ZooKeeper
Distributed Synchronization :: Control access to a shared resource across processes of a distributed application using ZooKeeper
ZooKeeper being a distributed coordination service is a distributed application in itself with a set of servers (nodes) providing the reliable coordination service. This set of ZooKeeper servers (nodes) providing the reliable coordination service is called an ensemble.
The following Figure-1 is an illustration of an Ensemble:
ZooKeeper allows the processes in a cluster-aware distributed application to coordinate with each other through a shared hierarchical namespace which is organized similarly to the standard file system. The hierarchical namespace consists of data registers that can hold some amount of data as byte array (upto 1MB) and are called znodes. Think of these znodes as similar to a directory in a standard file system.
The following Figure-2 is an illustration of the znodes hierarchy:
Each of the znodes in the ZooKeeper namespace is identified by a name, which is a sequence of path elements separated by a slash (/). From the above example, the znode S2 is identified by the name /T1/S2.
The znodes hierarchy (along with data) is stored in-memory within each of the ZooKeeper servers in the ensemble. This allows ZooKeeper to achieve high-throughput and low-latency and respond quickly to reads from the clients. Each ZooKeeper server also maintains a snapshot of the in-memory structure as well as a transaction log on the disk for persistent store.
Any updates to the znode hierarchy (including data) is replicated amongst the servers in the ensemble.
ZooKeeper exposes a very simple set of primitive operations which are as follows:
Operation | Description |
---|---|
create <path> <data> | Creates a znode at the appropriate location in the hierarchical namespace as specified by the <path> containing the specified <data> |
exists <path> | Checks if the znode exists at the location as specified by the <path> |
stat <path> | Returns the metadata information associated with the znode for the specified by the <path>. Metadata includes information such as creation time, last modification time, version number, etc |
getData <path> | Returns data contained in the znode at the location as specified by the <path> |
setData <path> <data> | Sets the data contained in the znode at the location as specified by the <path> to the specified <data> |
getChildren <path> | Returns a list of all the children under the znode as specified by the <path> |
delete <path> | Deletes the znode at the location as specified by the <path> |
A distributed application (client) can leverage the above mentioned primitives to create higher level distributed operations such as Configuration Management, Naming Service, Group Membership, etc.
Client(s) can connect to the ensemble and issue requests for the above mentioned primitives. At any given moment in time, a client is connected to only one of the servers in the ensemble. The client periodically checks to see if the server it is connected is alive. If the client detects the server as dead, then the client automatically connects to a different server in the ensemble.
When a client issues a read request on a znode, the read request is serviced from the local replica of the server that the client is connected to.
On the other hand, when the client issues a write request on a znode, the actual write request is processed by the leader of the ensemble. When the ZooKeeper service is initialized, one servers from the ensemble is elected as the leader (see Figure.1). The remaining servers are the followers. When a client issues a write request, the server the client is connected to passes on the request to the leader. This leader then issues the same write request to a quoram of servers (N/2+1) in the ensemble. If the write request on the quorum of servers succeeds, the write request is considered successful.
A znode can be created as being either persistent or ephemeral. A persistent znode can only be deleted using the delete primitive. An ephemeral znode on the other hand, will be deleted when the client that created the znode either crashes or closes its connection gracefully.
A znode maintains metadata just like the standard filesystem. The metadata includes information such as when the znode was created, when the znode was last modified, length of data in the znode, version number of the data in the znode, etc.
The version number is incremented each time the data in the znode is modified.
A client can register for notification of changes to a znode. This is referred to as a watch. A watch is one-time trigger event that is sent to the client that set it. The trigger event occurs when the data corresponding to the znode changes.
Installation and Setup On a 3-node Cluster
Ensure there are at least 3 Ubuntu 64-bit based Linux nodes in the cluster. Let us assume the IP addresses of the 3 nodes be: 192.168.1.1, 192.168.1.2, and 192.168.1.3 respectively.
Download the latest stable version (3.4.6 as of 05/10/2014) of Apache ZooKeeper from the project site located at the URL zookeeper.apache.org/releases.html
Following are the steps to install and setup Apache ZooKeeper on a Ubuntu 64-bit based Linux workstation:
Ensure Java SE 7 or above is installed on your system
Extract the downloaded package zookeeper-3.4.6.tar.gz to a desired directory location (say, /home/zkuser/zookeper). Let us refer to it as ZOOKEEPER_HOME
mkdir -p $ZOOKEEPER_HOME/data
Copy the file $ZOOKEEPER_HOME/conf/zoo_sample.cfg to $ZOOKEEPER_HOME/conf/zoo.cfg
Modify the contents of the file $ZOOKEEPER_HOME/conf/zoo.cfg to be as follows:
tickTime=2000 initLimit=5 syncLimit=2 dataDir=/home/zkuser/zookeeper/data dataLogDir=/home/zkuser/zookeeper/data clientPort=2181 server.1=192.168.1.1:2888:3888 server.2=192.168.1.2:2888:3888 server.3=192.168.1.3:2888:3888
On the node 192.168.1.1, create a file named myid under the directory $ZOOKEEPER_HOME/data with the value 1
On the node 192.168.1.2, create a file named myid under the directory $ZOOKEEPER_HOME/data with the value 2
On the node 192.168.1.3, create a file named myid under the directory $ZOOKEEPER_HOME/data with the value 3
On each of the 3 nodes, execute the command: $ZOOKEEPER_HOME/bin/zkServer.sh start-foreground
This will startup the ZooKeeper service on the 3-node cluster.
This following is the output from the node 192.168.1.1:
zkuser@my-host:$ $ZOOKEEPER_HOME/bin/zkServer.sh start-foreground JMX enabled by default Using config: /home/zkuser/zookeeper/bin/../conf/zoo.cfg 2014-05-09 16:41:48,323 [myid:] - INFO [main:QuorumPeerConfig@103] - Reading configuration from: /home/zkuser/zookeeper/bin/../conf/zoo.cfg 2014-05-09 16:41:48,329 [myid:] - INFO [main:QuorumPeerConfig@340] - Defaulting to majority quorums 2014-05-09 16:41:48,338 [myid:1] - INFO [main:DatadirCleanupManager@78] - autopurge.snapRetainCount set to 3 2014-05-09 16:41:48,338 [myid:1] - INFO [main:DatadirCleanupManager@79] - autopurge.purgeInterval set to 0 2014-05-09 16:41:48,339 [myid:1] - INFO [main:DatadirCleanupManager@101] - Purge task is not scheduled. 2014-05-09 16:41:48,363 [myid:1] - INFO [main:QuorumPeerMain@127] - Starting quorum peer 2014-05-09 16:41:48,434 [myid:1] - INFO [main:NIOServerCnxnFactory@94] - binding to port 0.0.0.0/0.0.0.0:2181 2014-05-09 16:41:48,456 [myid:1] - INFO [main:QuorumPeer@959] - tickTime set to 2000 2014-05-09 16:41:48,456 [myid:1] - INFO [main:QuorumPeer@979] - minSessionTimeout set to -1 2014-05-09 16:41:48,456 [myid:1] - INFO [main:QuorumPeer@990] - maxSessionTimeout set to -1 2014-05-09 16:41:48,456 [myid:1] - INFO [main:QuorumPeer@1005] - initLimit set to 5 2014-05-09 16:41:48,477 [myid:1] - INFO [main:QuorumPeer@473] - currentEpoch not found! Creating with a reasonable default of 0. This should only happen when you are upgrading your installation 2014-05-09 16:41:48,507 [myid:1] - INFO [main:QuorumPeer@488] - acceptedEpoch not found! Creating with a reasonable default of 0. This should only happen when you are upgrading your installation 2014-05-09 16:41:48,552 [myid:1] - INFO [Thread-1:QuorumCnxManager$Listener@504] - My election bind port: /192.168.1.6:3888 2014-05-09 16:41:48,565 [myid:1] - INFO [QuorumPeer[myid=1]/0:0:0:0:0:0:0:0:2181:QuorumPeer@714] - LOOKING 2014-05-09 16:41:48,568 [myid:1] - INFO [QuorumPeer[myid=1]/0:0:0:0:0:0:0:0:2181:FastLeaderElection@815] - New election. My id = 1, proposed zxid=0x0 2014-05-09 16:41:48,571 [myid:1] - INFO [WorkerReceiver[myid=1]:FastLeaderElection@597] - Notification: 1 (message format version), 1 (n.leader), 0x0 (n.zxid), 0x1 (n.round), LOOKING (n.state), 1 (n.sid), 0x0 (n.peerEpoch) LOOKING (my state) 2014-05-09 16:41:48,579 [myid:1] - WARN [WorkerSender[myid=1]:QuorumCnxManager@382] - Cannot open channel to 2 at election address /192.168.1.2:3888 java.net.ConnectException: Connection refused at java.net.PlainSocketImpl.socketConnect(Native Method) at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:345) at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206) at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188) at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392) at java.net.Socket.connect(Socket.java:589) at org.apache.zookeeper.server.quorum.QuorumCnxManager.connectOne(QuorumCnxManager.java:368) at org.apache.zookeeper.server.quorum.QuorumCnxManager.toSend(QuorumCnxManager.java:341) at org.apache.zookeeper.server.quorum.FastLeaderElection$Messenger$WorkerSender.process(FastLeaderElection.java:449) at org.apache.zookeeper.server.quorum.FastLeaderElection$Messenger$WorkerSender.run(FastLeaderElection.java:430) at java.lang.Thread.run(Thread.java:745) 2014-05-09 16:41:48,589 [myid:1] - WARN [WorkerSender[myid=1]:QuorumCnxManager@382] - Cannot open channel to 3 at election address /192.168.1.3:3888 java.net.ConnectException: Connection refused at java.net.PlainSocketImpl.socketConnect(Native Method) at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:345) at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206) at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188) at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392) at java.net.Socket.connect(Socket.java:589) at org.apache.zookeeper.server.quorum.QuorumCnxManager.connectOne(QuorumCnxManager.java:368) at org.apache.zookeeper.server.quorum.QuorumCnxManager.toSend(QuorumCnxManager.java:341) at org.apache.zookeeper.server.quorum.FastLeaderElection$Messenger$WorkerSender.process(FastLeaderElection.java:449) at org.apache.zookeeper.server.quorum.FastLeaderElection$Messenger$WorkerSender.run(FastLeaderElection.java:430) at java.lang.Thread.run(Thread.java:745) 2014-05-09 16:42:14,013 [myid:1] - INFO [QuorumPeer[myid=1]/0:0:0:0:0:0:0:0:2181:FastLeaderElection@849] - Notification time out: 25600 2014-05-09 16:42:22,296 [myid:1] - INFO [/192.168.1.6:3888:QuorumCnxManager$Listener@511] - Received connection request /192.168.1.3:60368 2014-05-09 16:42:22,302 [myid:1] - INFO [WorkerReceiver[myid=1]:FastLeaderElection@597] - Notification: 1 (message format version), 3 (n.leader), 0x0 (n.zxid), 0x1 (n.round), LOOKING (n.state), 3 (n.sid), 0x0 (n.peerEpoch) LOOKING (my state) 2014-05-09 16:42:22,303 [myid:1] - INFO [WorkerReceiver[myid=1]:FastLeaderElection@597] - Notification: 1 (message format version), 3 (n.leader), 0x0 (n.zxid), 0x1 (n.round), LOOKING (n.state), 1 (n.sid), 0x0 (n.peerEpoch) LOOKING (my state) 2014-05-09 16:42:22,305 [myid:1] - WARN [WorkerSender[myid=1]:QuorumCnxManager@382] - Cannot open channel to 2 at election address /192.168.1.2:3888 java.net.ConnectException: Connection refused at java.net.PlainSocketImpl.socketConnect(Native Method) at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:345) at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206) at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188) at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392) at java.net.Socket.connect(Socket.java:589) at org.apache.zookeeper.server.quorum.QuorumCnxManager.connectOne(QuorumCnxManager.java:368) at org.apache.zookeeper.server.quorum.QuorumCnxManager.toSend(QuorumCnxManager.java:341) at org.apache.zookeeper.server.quorum.FastLeaderElection$Messenger$WorkerSender.process(FastLeaderElection.java:449) at org.apache.zookeeper.server.quorum.FastLeaderElection$Messenger$WorkerSender.run(FastLeaderElection.java:430) at java.lang.Thread.run(Thread.java:745) 2014-05-09 16:42:22,504 [myid:1] - INFO [QuorumPeer[myid=1]/0:0:0:0:0:0:0:0:2181:QuorumPeer@784] - FOLLOWING 2014-05-09 16:42:22,523 [myid:1] - INFO [QuorumPeer[myid=1]/0:0:0:0:0:0:0:0:2181:Learner@86] - TCP NoDelay set to: true 2014-05-09 16:42:22,557 [myid:1] - INFO [QuorumPeer[myid=1]/0:0:0:0:0:0:0:0:2181:Environment@100] - Server environment:zookeeper.version=3.4.6-1569965, built on 02/20/2014 09:09 GMT 2014-05-09 16:42:22,557 [myid:1] - INFO [QuorumPeer[myid=1]/0:0:0:0:0:0:0:0:2181:Environment@100] - Server environment:host.name=my-host 2014-05-09 16:42:22,558 [myid:1] - INFO [QuorumPeer[myid=1]/0:0:0:0:0:0:0:0:2181:Environment@100] - Server environment:java.version=1.8.0_05 2014-05-09 16:42:22,558 [myid:1] - INFO [QuorumPeer[myid=1]/0:0:0:0:0:0:0:0:2181:Environment@100] - Server environment:java.vendor=Oracle Corporation 2014-05-09 16:42:22,558 [myid:1] - INFO [QuorumPeer[myid=1]/0:0:0:0:0:0:0:0:2181:Environment@100] - Server environment:java.home=/usr/lib/jvm/java-8-oracle/jre 2014-05-09 16:42:22,558 [myid:1] - INFO [QuorumPeer[myid=1]/0:0:0:0:0:0:0:0:2181:Environment@100] - Server environment:java.class.path=/home/zkuser/zookeeper/bin/../build/classes:/home/zkuser/zookeeper/bin/../build/lib/*.jar:/home/zkuser/zookeeper/bin/../lib/zookeeper-3.4.6.jar:/home/zkuser/zookeeper/bin/../lib/slf4j-log4j12-1.6.1.jar:/home/zkuser/zookeeper/bin/../lib/slf4j-api-1.6.1.jar:/home/zkuser/zookeeper/bin/../lib/netty-3.7.0.Final.jar:/home/zkuser/zookeeper/bin/../lib/log4j-1.2.16.jar:/home/zkuser/zookeeper/bin/../lib/jline-0.9.94.jar:/home/zkuser/zookeeper/bin/../zookeeper-*.jar:/home/zkuser/zookeeper/bin/../src/java/lib/*.jar:/home/zkuser/zookeeper/bin/../conf: 2014-05-09 16:42:22,558 [myid:1] - INFO [QuorumPeer[myid=1]/0:0:0:0:0:0:0:0:2181:Environment@100] - Server environment:java.library.path=/usr/java/packages/lib/amd64:/usr/lib64:/lib64:/lib:/usr/lib 2014-05-09 16:42:22,559 [myid:1] - INFO [QuorumPeer[myid=1]/0:0:0:0:0:0:0:0:2181:Environment@100] - Server environment:java.io.tmpdir=/tmp 2014-05-09 16:42:22,559 [myid:1] - INFO [QuorumPeer[myid=1]/0:0:0:0:0:0:0:0:2181:Environment@100] - Server environment:java.compiler=<NA> 2014-05-09 16:42:22,559 [myid:1] - INFO [QuorumPeer[myid=1]/0:0:0:0:0:0:0:0:2181:Environment@100] - Server environment:os.name=Linux 2014-05-09 16:42:22,559 [myid:1] - INFO [QuorumPeer[myid=1]/0:0:0:0:0:0:0:0:2181:Environment@100] - Server environment:os.arch=amd64 2014-05-09 16:42:22,560 [myid:1] - INFO [QuorumPeer[myid=1]/0:0:0:0:0:0:0:0:2181:Environment@100] - Server environment:os.version=3.13.0-24-generic 2014-05-09 16:42:22,560 [myid:1] - INFO [QuorumPeer[myid=1]/0:0:0:0:0:0:0:0:2181:Environment@100] - Server environment:user.name=zkuser 2014-05-09 16:42:22,560 [myid:1] - INFO [QuorumPeer[myid=1]/0:0:0:0:0:0:0:0:2181:Environment@100] - Server environment:user.home=/home/zkuser 2014-05-09 16:42:22,561 [myid:1] - INFO [QuorumPeer[myid=1]/0:0:0:0:0:0:0:0:2181:Environment@100] - Server environment:user.dir=/home/zkuser/zookeeper 2014-05-09 16:42:22,565 [myid:1] - INFO [QuorumPeer[myid=1]/0:0:0:0:0:0:0:0:2181:ZooKeeperServer@162] - Created server with tickTime 2000 minSessionTimeout 4000 maxSessionTimeout 40000 datadir /home/zkuser/zookeeper/data/version-2 snapdir /home/zkuser/zookeeper/data/version-2 2014-05-09 16:42:22,568 [myid:1] - INFO [QuorumPeer[myid=1]/0:0:0:0:0:0:0:0:2181:Follower@63] - FOLLOWING - LEADER ELECTION TOOK - 34001 2014-05-09 16:42:22,572 [myid:1] - WARN [QuorumPeer[myid=1]/0:0:0:0:0:0:0:0:2181:Learner@233] - Unexpected exception, tries=0, connecting to /192.168.1.3:2888 java.net.ConnectException: Connection refused at java.net.PlainSocketImpl.socketConnect(Native Method) at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:345) at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206) at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188) at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392) at java.net.Socket.connect(Socket.java:589) at org.apache.zookeeper.server.quorum.Learner.connectToLeader(Learner.java:225) at org.apache.zookeeper.server.quorum.Follower.followLeader(Follower.java:71) at org.apache.zookeeper.server.quorum.QuorumPeer.run(QuorumPeer.java:786) 2014-05-09 16:42:23,655 [myid:1] - INFO [QuorumPeer[myid=1]/0:0:0:0:0:0:0:0:2181:Learner@323] - Getting a diff from the leader 0x0 2014-05-09 16:42:23,660 [myid:1] - INFO [QuorumPeer[myid=1]/0:0:0:0:0:0:0:0:2181:FileTxnSnapLog@240] - Snapshotting: 0x0 to /home/zkuser/zookeeper/data/version-2/snapshot.0 2014-05-09 16:42:43,770 [myid:1] - INFO [/192.168.1.1:3888:QuorumCnxManager$Listener@511] - Received connection request /192.168.1.2:50429 2014-05-09 16:42:43,776 [myid:1] - INFO [WorkerReceiver[myid=1]:FastLeaderElection@597] - Notification: 1 (message format version), 2 (n.leader), 0x0 (n.zxid), 0x1 (n.round), LOOKING (n.state), 2 (n.sid), 0x0 (n.peerEpoch) FOLLOWING (my state) 2014-05-09 16:42:43,781 [myid:1] - INFO [WorkerReceiver[myid=1]:FastLeaderElection@597] - Notification: 1 (message format version), 3 (n.leader), 0x0 (n.zxid), 0x1 (n.round), LOOKING (n.state), 2 (n.sid), 0x0 (n.peerEpoch) FOLLOWING (my state) 2014-05-09 16:46:25,379 [myid:1] - INFO [NIOServerCxn.Factory:0.0.0.0/0.0.0.0:2181:NIOServerCnxnFactory@197] - Accepted socket connection from /127.0.0.1:34668 2014-05-09 16:46:25,393 [myid:1] - INFO [NIOServerCxn.Factory:0.0.0.0/0.0.0.0:2181:NIOServerCnxn@827] - Processing srvr command from /127.0.0.1:34668 2014-05-09 16:46:25,397 [myid:1] - INFO [Thread-2:NIOServerCnxn@1007] - Closed socket connection for client /127.0.0.1:34668 (no session established for client)
Do not worry about the exceptions from the Output.1 above; it is from the Leader Election process as we start the ZooKeeper server in each of the 3 nodes one-by-one.
Hands-on with Apache ZooKeeper
Apache ZooKeeper has a command-line client $ZOOKEEPER_HOME/bin/zkCli.sh, which behaves like an interactive shell. In the following paragraphs we will explore some of the primitives of ZooKeeper.
To launch the interactive ZooKeeper client, execute the following command:
$ZOOKEEPER_HOME/bin/zkCli.sh -server 192.168.1.6:2181,192.168.1.3:2181,192.168.1.13:2181
The following will be the output:
Connecting to 192.168.1.1:2181,192.168.1.2:2181,192.168.1.3:2181 2014-05-09 22:57:17,975 [myid:] - INFO [main:Environment@100] - Client environment:zookeeper.version=3.4.6-1569965, built on 02/20/2014 09:09 GMT 2014-05-09 22:57:17,978 [myid:] - INFO [main:Environment@100] - Client environment:host.name=my-host 2014-05-09 22:57:17,979 [myid:] - INFO [main:Environment@100] - Client environment:java.version=1.8.0_05 2014-05-09 22:57:17,981 [myid:] - INFO [main:Environment@100] - Client environment:java.vendor=Oracle Corporation 2014-05-09 22:57:17,981 [myid:] - INFO [main:Environment@100] - Client environment:java.home=/usr/lib/jvm/java-8-oracle/jre 2014-05-09 22:57:17,981 [myid:] - INFO [main:Environment@100] - Client environment:java.class.path=/home/zkuser/zookeeper/bin/../build/classes:/home/zkuser/zookeeper/bin/../build/lib/*.jar:/home/zkuser/zookeeper/bin/../lib/zookeeper-3.4.6.jar:/home/zkuser/zookeeper/bin/../lib/slf4j-log4j12-1.6.1.jar:/home/zkuser/zookeeper/bin/../lib/slf4j-api-1.6.1.jar:/home/zkuser/zookeeper/bin/../lib/netty-3.7.0.Final.jar:/home/zkuser/zookeeper/bin/../lib/log4j-1.2.16.jar:/home/zkuser/zookeeper/bin/../lib/jline-0.9.94.jar:/home/zkuser/zookeeper/bin/../zookeeper-*.jar:/home/zkuser/zookeeper/bin/../src/java/lib/*.jar:/home/zkuser/zookeeper/bin/../conf: 2014-05-09 22:57:17,981 [myid:] - INFO [main:Environment@100] - Client environment:java.library.path=/usr/java/packages/lib/amd64:/usr/lib64:/lib64:/lib:/usr/lib 2014-05-09 22:57:17,981 [myid:] - INFO [main:Environment@100] - Client environment:java.io.tmpdir=/tmp 2014-05-09 22:57:17,981 [myid:] - INFO [main:Environment@100] - Client environment:java.compiler=<NA> 2014-05-09 22:57:17,981 [myid:] - INFO [main:Environment@100] - Client environment:os.name=Linux 2014-05-09 22:57:17,981 [myid:] - INFO [main:Environment@100] - Client environment:os.arch=amd64 2014-05-09 22:57:17,981 [myid:] - INFO [main:Environment@100] - Client environment:os.version=3.13.0-24-generic 2014-05-09 22:57:17,982 [myid:] - INFO [main:Environment@100] - Client environment:user.name=zkuser 2014-05-09 22:57:17,982 [myid:] - INFO [main:Environment@100] - Client environment:user.home=/home/zkuser 2014-05-09 22:57:17,982 [myid:] - INFO [main:Environment@100] - Client environment:user.dir=/home/zkuser/zookeeper 2014-05-09 22:57:17,983 [myid:] - INFO [main:ZooKeeper@438] - Initiating client connection, connectString=192.168.1.6:2181,192.168.1.3:2181,192.168.1.13:2181 sessionTimeout=30000 watcher=org.apache.zookeeper.ZooKeeperMain$MyWatcher@506c589e Welcome to ZooKeeper! 2014-05-09 22:57:18,009 [myid:] - INFO [main-SendThread(192.168.1.3:2181):ClientCnxn$SendThread@975] - Opening socket connection to server 192.168.1.1/192.168.1.1:2181. Will not attempt to authenticate using SASL (unknown error) JLine support is enabled 2014-05-09 22:57:18,013 [myid:] - INFO [main-SendThread(192.168.1.1:2181):ClientCnxn$SendThread@852] - Socket connection established to 192.168.1.1/192.168.1.1:2181, initiating session [zk: 192.168.1.6:2181,192.168.1.3:2181,192.168.1.13:2181(CONNECTING) 0] 2014-05-09 22:57:18,043 [myid:] - INFO [main-SendThread(192.168.1.1:2181):ClientCnxn$SendThread@1235] - Session establishment complete on server 192.168.1.1/192.168.1.1:2181, sessionid = 0x245e7dfa13a0001, negotiated timeout = 30000 WATCHER:: WatchedEvent state:SyncConnected type:None path:null [zk: 192.168.1.1:2181,192.168.1.2:2181,192.168.1.3:2181(CONNECTED) 0]
To list all the znodes in ZooKeeper hierarchical namespace, execute the following command:
[zk: 192.168.1.1:2181,192.168.1.2:2181,192.168.1.3:2181(CONNECTED) 0] ls /
The following will be the output:
[zookeeper]
The above output indicates that there is a default znode called zookeper.
To create a persistent znode named mytest with no data, execute the following command:
[zk: 192.168.1.1:2181,192.168.1.2:2181,192.168.1.3:2181(CONNECTED) 0] create /mytest ""
The following will be the output:
Created /mytest
To again list all the znodes in ZooKeeper, execute the following command:
[zk: 192.168.1.1:2181,192.168.1.2:2181,192.168.1.3:2181(CONNECTED) 0] ls /
The following will be the output:
[mytest, zookeeper]
To create an ephemeral znode named mytemp with no data, execute the following command:
[zk: 192.168.1.1:2181,192.168.1.2:2181,192.168.1.3:2181(CONNECTED) 0] create -e /mytemp ""
The following will be the output:
Created /mytemp
To again list all the znodes in ZooKeeper, execute the following command:
[zk: 192.168.1.1:2181,192.168.1.2:2181,192.168.1.3:2181(CONNECTED) 0] ls /
The following will be the output:
[mytemp, mytest, zookeeper]
To close the client connection to ZooKeeper and quit the interactive shell, execute the following command:
[zk: 192.168.1.1:2181,192.168.1.2:2181,192.168.1.3:2181(CONNECTED) 0] quit
The following will be the output:
Quitting... 2014-05-09 22:55:42,255 [myid:] - INFO [main:ZooKeeper@684] - Session: 0x245e7dfa13a0000 closed 2014-05-09 22:55:42,255 [myid:] - INFO [main-EventThread:ClientCnxn$EventThread@512] - EventThread shut down
Now, re-launch the interactive ZooKeeper client by executing the following command:
$ZOOKEEPER_HOME/bin/zkCli.sh -server 192.168.1.6:2181,192.168.1.3:2181,192.168.1.13:2181
And issue the command to list all the znodes in ZooKeeper by executing the following command:
[zk: 192.168.1.1:2181,192.168.1.2:2181,192.168.1.3:2181(CONNECTED) 0] ls /
The following will be the output:
[mytest, zookeeper]
As expected, the ephemeral znode with the path /mytemp has been automatically deleted.
To fetch the data stored in the znode named /mytest, execute the following command:
[zk: 192.168.1.1:2181,192.168.1.2:2181,192.168.1.3:2181(CONNECTED) 0] get /mytest
The following will be the output:
"" cZxid = 0x100000004 ctime = Sat May 10 22:52:50 EDT 2014 mZxid = 0x100000004 mtime = Sat May 10 22:52:50 EDT 2014 pZxid = 0x100000004 cversion = 0 dataVersion = 0 aclVersion = 0 ephemeralOwner = 0x0 dataLength = 2 numChildren = 0
The first line with the empty double quotes is the data. Remember we created the znode named /mytest with no data.
The get data command also displays the metadata information.
To display the metadata associate with the znode named /mytest, execute the following command:
[zk: 192.168.1.1:2181,192.168.1.2:2181,192.168.1.3:2181(CONNECTED) 0] stat /mytest
The following will be the output:
cZxid = 0x100000004 ctime = Sat May 10 22:52:50 EDT 2014 mZxid = 0x100000004 mtime = Sat May 10 22:52:50 EDT 2014 pZxid = 0x100000004 cversion = 0 dataVersion = 0 aclVersion = 0 ephemeralOwner = 0x0 dataLength = 2 numChildren = 0
To set the data stored in the znode named /mytest, execute the following command:
[zk: 192.168.1.1:2181,192.168.1.2:2181,192.168.1.3:2181(CONNECTED) 0] set /mytest "hello"
The following will be the output:
cZxid = 0x100000004 ctime = Sat May 10 22:52:50 EDT 2014 mZxid = 0x100000008 mtime = Sat May 10 23:05:48 EDT 2014 pZxid = 0x100000004 cversion = 0 dataVersion = 1 aclVersion = 0 ephemeralOwner = 0x0 dataLength = 7 numChildren = 0
As can be observed from the Output.12, the version number of the data at the znode named /mytest has been incremented to 1.
To add a watch on the znode named /mytest, execute the following command:
[zk: 192.168.1.1:2181,192.168.1.2:2181,192.168.1.3:2181(CONNECTED) 0] stat /mytest true
The following will be the output:
cZxid = 0x100000004 ctime = Sat May 10 22:52:50 EDT 2014 mZxid = 0x100000004 mtime = Sat May 10 23:05:48 EDT 2014 pZxid = 0x100000004 cversion = 0 dataVersion = 1 aclVersion = 0 ephemeralOwner = 0x0 dataLength = 7 numChildren = 0
To set a watch on a path, we can either use the stat command or the get command.
Now, let us again change (or modify) the data stored in the znode named /mytest by executing the following command:
[zk: 192.168.1.1:2181,192.168.1.2:2181,192.168.1.3:2181(CONNECTED) 0] set /mytest "world"
The following will be the output:
WATCHER:: WatchedEvent state:SyncConnected type:NodeDataChanged path:/mytest
cZxid = 0x100000004 ctime = Sat May 10 22:52:50 EDT 2014 mZxid = 0x100000008 mtime = Sat May 10 23:06:37 EDT 2014 pZxid = 0x100000004 cversion = 0 dataVersion = 2 aclVersion = 0 ephemeralOwner = 0x0 dataLength = 7 numChildren = 0
Notice the WatchedEvent fire in the above Output.14.
Finally, to delete the znode named /mytest, execute the following command:
[zk: 192.168.1.1:2181,192.168.1.2:2181,192.168.1.3:2181(CONNECTED) 0] delete /mytest
There will be no output.
Now issue the command to list all the znodes in ZooKeeper by executing the following command:
[zk: 192.168.1.1:2181,192.168.1.2:2181,192.168.1.3:2181(CONNECTED) 0] ls /
The following will be the output:
[zookeeper]