Unlock the Power: Spring Boot and Zookeeper for Seamless Distributed Locks!
Leveraging curator framework with Spring Boot to unlock the power of Zookeeper
What are distributed locks?
Distributed locks serve as a vital tool in distributed computing, facilitating the coordination and synchronisation of access to shared resources or critical sections across multiple nodes or processes. Their primary goal is to guarantee exclusive access to a specific resource by only one node or process at a time. This prevents conflicts and plays a key role in preserving data consistency within a distributed system.
Advantages of using Zookeeper
- It is designed with a strong focus on providing a highly consistent and reliable distributed coordination service. It ensures a strict order of operations, which is crucial for maintaining integrity in distributed systems
- It assigns sequential and incremental node IDs when creating znodes (Zookeeper nodes). This feature is beneficial for scenarios where the order of lock acquisition matters, ensuring a clear and predictable sequence of operations
- It supports a watch mechanism that allows clients to receive notifications when the state of a znode changes. This can be useful for building more sophisticated distributed systems that react to changes in the locking state
- It was explicitly designed as a distributed coordination service and has been widely used for this purpose in various large-scale systems. It has a mature and battle-tested architecture for distributed consensus
- It uses a quorum-based approach for achieving consensus, which involves a majority of nodes agreeing on a particular state. This contributes to its robustness in distributed scenarios
Spring Boot: A Natural Companion
Spring Boot, known for simplifying the development of Java applications, seamlessly integrates with Zookeeper to enhance the coordination capabilities of distributed systems. Its convention-over-configuration approach and extensive ecosystem make it an excellent fit for building robust and scalable applications.
Unlocking the Synergy
When Spring Boot and Zookeeper join forces, developers gain a potent toolkit for implementing distributed locks. Sequential node IDs, watch mechanisms, and the ability to handle complex coordination scenarios make the combination a compelling choice for projects requiring seamless distributed locking.
Now it’s time to move from theory and look at how we can implement the same in Spring Boot. Also as a pre-requisite, make sure that zookeeper server is up and running. In order to setup locally, you can follow https://zookeeper.apache.org/doc/r3.1.2/zookeeperStarted.html
Bootstrap the Project
SpringBoot projects are very easy to initalize. One can either use IntelliJ IDEA or can visit https://start.spring.io/ and after filling all the project details, can click on GENERATE button which will download the ZIP
- Once the ZIP is downloaded, extract the project and open the same in your preferred IDE
- Let’s add/update a couple of dependencies. Edit your build.gradle file, import the below dependencies and run gradle sync
implementation('org.springframework.cloud:spring-cloud-starter-zookeeper-all') {
exclude group: 'org.apache.zookeeper', module: 'zookeeper'
}
implementation('org.apache.zookeeper:zookeeper:3.8.0')
Let’s start with Zookeeper implementation
- Create a zookeeper package and an interface as ZookeeperService which we are going to autowire
and now let’s start with implementation.
Note: I have implemented other functions as well which might be helpful as part of other implementation
All the Zookeeper implementations are now ready and can be imported in our service. Below is the sample implementation for the same
@Autowired
private ZooKeeperService zooKeeper;
public boolean setLock(String key) throws Exception {
log.info("setting lock on key " + key);
String zkey = "/key/"+key;
if(zooKeeper.exists(zkey)) {
log.warn("lock already applied on this key");
return false;
}
zooKeeper.create(zkey, String.valueOf(LocalTime.now()));
zooKeeper.lock(zkey);
return true;
}
public boolean unlock(String key) throws Exception {
log.info("unlock the key " + key);
String zkey = "/key/"+key;
if (!zooKeeper.exists(zkey)) {
log.warn("lock already released");
return false;
}
zooKeeper.release(zkey);
zooKeeper.delete(zkey);
return true;
}
Instead of a standard hash table, it stores the entries in a tree like data structure. Each node of the tree is referred to as a Znode.
I won’t go into much of details as implementation depends on use-case. The complete code can be found in the repository here.
Zookeeper is a wonderful high-performance coordination service for distributed applications by Apache. I would love to hear the different use-cases for which your organization uses Zookeeper for.
In case you have any doubts feel free to open an issue on the repository and we can discuss over there 😄 Also you can reach out to me over twitter https://twitter.com/jvinamra776 and don’t forget to clap if you like the blog 😉