Nov 13, 2016

First experiments with Apache ZooKeeper - a distributed Key-Value Store.

Apache ZooKeeper is a distributed Key/Value Store and more, which can be used as a kind of
registry for the currently modern MicroServices architecture.

My first attempts were to let 3 instances run as a Docker Container.

As the base for my start, I used the available docker image jplock/zookeeper from the docker registry.

Before starting with the zookeeper containers, I built my own image by adding my own configuration  for zookeeper:

FROM jplock/zookeeper
MAINTAINER ......

ADD conf/zoo.cfg /opt/zookeeper/conf/zoo.cfg

The content of zoo.cfg is:

# The number of milliseconds of each tick
tickTime=2000
# The number of ticks that the initial
# synchronization phase can take
initLimit=10
# The number of ticks that can pass between
# sending a request and getting an acknowledgement
syncLimit=5
# the directory where the snapshot is stored.
# do not use /tmp for storage, /tmp here is just
# example sakes.
dataDir=/tmp/zookeeper
# the port at which the clients will connect
clientPort=2181
server.1=zoo1:2888:3888
server.2=zoo2:2888:3888
server.3=zoo2:2888:3888

And the containers are started up with the help of docker-compose with the following 
docker-compose.yml configuration: 

version: '2'

services:
  zoomaster:
    image: ewer/zookeeper
    ports:
      - "2181:2181"
    expose:
      - "2181"
      - "2888"
      - "3888"
    labels:
      zookeeper: master
    volumes:
      - /c/Users/name/docker_volumes/zoo1:/tmp/zookeeper
    container_name: zoo1
  zooclient2:
    image: ewer/zookeeper
    ports:
      - "2182:2181"
    expose:
        - "2181"
        - "2888"
        - "3888"
    labels:
      zookeeper: master
    volumes:
      - /c/Users/name/docker_volumes/zoo2:/tmp/zookeeper
    container_name: zoo2
  zooclient3:
    image: ewer/zookeeper
    ports:
      - "2183:2181"
    expose:
      - "2181"
      - "2888"
      - "3888"
    labels:
      zookeeper: master
    volumes:
      - /c/Users/name/docker_volumes/zoo3:/tmp/zookeeper
    container_name: zoo3

As you can see in the volumes, per default only the homedirectory is mounted into the 
boot2docker Image of the docker engine, using the cygwin path 
A precondition zookeeper needs is a file called myid in /tmp/zookeeper with sequential numbers. 


After creating a docker machine on windows with 
docker-machine.exe create java

and setting the environment by the help of 
docker-machine.exe env java 


docker-compose up -d 

After installing a local version of zookeeper to get the commandline client the first test could be 
done: 

The IP-Adress is the one from the docker-machine ( retrieved by docker-machine.exe env java )
and the port is sequentially configured for each container in the docker-compose.yml

Connecting to the container zoo1 and creating some data: 
PS C:\dev\Docker\zookeeper\zookeeper-3.4.9\bin> ./zkCli.cmd -server 192.168.99.100:2181
[zk: 192.168.99.100:2181(CONNECTED) 19] create /vsop 1
Created /vsop
[zk: 192.168.99.100:2181(CONNECTED) 20] create /vsop/eaiserver 1
Created /vsop/eaiserver
[zk: 192.168.99.100:2181(CONNECTED) 21] create /vsop/eaiserver/port  8181
Created /vsop/eaiserver/port
[zk: 192.168.99.100:2181(CONNECTED) 22] ls /vsop
[eaiserver]
[zk: 192.168.99.100:2181(CONNECTED) 23] ls /vsop/eaiserver/port
[]
[zk: 192.168.99.100:2181(CONNECTED) 24] get /vsop/eaiserver/port
8181

Now connect to the container zoo2 and check the data there: 

PS C:\dev\Docker\zookeeper\zookeeper-3.4.9\bin> ./zkCli.cmd -server 192.168.99.100:2182
[zk: 192.168.99.100:2182(CONNECTED) 24] get /vsop/eaiserver/port
8181
cZxid = 0x60000000d
ctime = Sat Nov 12 18:42:15 MST 2016
mZxid = 0x60000000d
mtime = Sat Nov 12 18:42:15 MST 2016
pZxid = 0x60000000d
cversion = 0
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 4
numChildren = 0