What problem does it solve?
Let's imagine we have a million files in a file store and the file count keeps increasing every minute of the day.
Our task is to first process and then delete these files. One of the approach we can think of is to write a script that does this task and run multiple instances parallelly on multiple servers. We can even increase or decrease the server count based on the demand. This is basically a distributed compute/data processing application.
Here, how can we ensure that the same file is not picked and processed by multiple servers at the same time?
To solve this problem, all the servers should share the information b/w them regarding which file is currently being processed.
This is where we can use something like ZooKeeper. When the first server wants to read a file, it can write to the zookeeper the file name its going to process. Now the rest of the servers can look up ZooKeeper and know that this file is already picked up by the first server.
Above is a crude example and needs few other guard rails in place but I hope it gives an idea on what zookeeper is.
ZK is basically a data store which can be accessed using the ZK API's. But it should NOT be used as a database. Only a small amount of data should be stored(usually in KB's). The upper limit is 1MB per znode.
ZK is specifically built so that the distributed applications can communicate among each other.
Applications of ZK
Out of the box can be used for
- storing configuration: to store configuration that is accessed
across your distributed application.
- naming service: store information such as service name and IP address mapping in a central place, which enables
users and applications to communicate across the network.
- group membership: all the applications running on distributed servers can connect to ZK and send heartbeats. If any one server/application goes down then ZK can alert other
servers/applications regarding this event.
Other features have to be built on top of the ZooKeeper API.
- locks and queues - useful for distributed synchronization.
- two phase commits - useful when we have to commit/rollback across
servers.
- leader election - your distributed applications can use ZK to hold leader elections for automatic failovers.
- shared counter
Below is the page that explains how these features can be implemented
https://zookeeper.apache.org/doc/current/recipes.html
ZooKeeper can have many more applications. The features have to be built on top of ZK API's based on the requirements of your distributed system.
NOTE: ZK should not be used to store large amounts of data. Its not a cache/database. Use it to exchange small piece of information that your distributed applications need to start, operate and failover.
How data is stored?
Data is stored in a hierarchical tree data structure. Each node in the tree is called znode. Max size of a znode is 1MB. znodes can have data and other children znodes. Think of a znode like a folder on your computer where the folder can have files with data but also the folder itself can have data just like a file.
Why use ZK instead of our own custom service?
- Atomicity and Durability
- Zookeeper itself is distributed and Fault tolerant. The architecture involves one leader node and multiple follower nodes. In case a ZK follower node goes down, it will automatically failover. The client sessions are replicated hence ZK can automatically move clients to a different node. If the
Leader node goes down then a new leader is elected using the ZK
consensus algorithm.
- Reads are very fast since its served from in-memory store.
- Writes are written in the sequence in which it arrived. Hence maintains ordering.
- Watches will send out notification to the client who set the watch on some data. This reduces the need to poll ZK. Note that watches are one time triggers and if you get a watch event and you want to get notified of future changes, you must set another watch.
- Persistent and ephemeral znodes are available. Both are stored on ZK disks. Persistent here means that the data will be persisted once the client who created it disconnects. Ephemeral means the data will be removed automatically when the client disconnects. Ephemeral znodes are not allowed to have children.
- There is also persistent sequential and ephemeral sequential znodes. Here the names of the znodes can have a suffix sequence number. similar to DB auto increment ID's, these sequence number keeps increasing and managed by ZK. This can be useful to implement queues, locks etc.
Is there any application which is comparable to Zookeeper?
etcd - https://etcd.io/docs/v3.3/learning/why/#zookeeper