Recently at my work I came across the need for distributed locks, so I did some investigation and a small prototype to check how it can be done. Here you can see my findings so perhaps I will save somebody some time if they are ever in the same situation as me.
What are distributed locks? - they provide software applications which are distributed across a cluster on multiple machines with a means to synchronize their accesses to shared resources. More on the subject can be found on Wikipedia.
If you are looking for a good blog post about the subject I recommend Martin Kleppmann’s. In it you can find everything you need about the way it’s done. So in this blog post I will focus on the framework part of how it’s done.
You have a few a few frameworks you can choose from:
They are ordered alphabetically, so you don’t think I favor Curator. So here are my two cents about each of them.
Apache Curator
Curator is based on Apache ZooKeeper and on their web page they have described it better then I can explain - Guava is to Java what Curator is to ZooKeeper.
Having that in mind, you will need to have ZooKeeper running to have locks. If you don’t already run ZooKeeper I wouldn’t suggest choosing this as your first pick. But if you already use ZooKeeper chances are you already know about Curator.
Apache Helix
Helix also uses ZooKeeper for distributed locks. Their tutorial about it can be found here. There you can find a code example on Git you can run (which I did).
Here is the output of the example:
One great thing that Helix offers is redistribution. In this example 3 instances are started and 12 locks are distributed among them. Once they are up and running the first instance is shut down which causes Helix to do the redistribution of the locks acquired by the interrupted instance among the live instances.
Also you can connect to your already running instance of ZooKeeper if you have it running, or you can spin off one from code - like it was done in the example provided on git.
Apache Ignite
Like they say on their web site - Apache Ignite In-Memory Data Fabric is a high-performance, integrated and distributed in-memory platform for computing and transacting on large-scale data sets in real-time, orders of magnitude faster than possible with traditional disk-based or flash technologies.
So distributed locks is only a fraction of what it can do. They have some documentation about it here.
Code sample is straightforward
One thing to keep in mind is that in Ignite, locks are supported only for TRANSACTIONAL atomicity mode, which can be configured via atomicityMode property of CacheConfiguration. So if you don’t set atomicity mode to transactional you won’t even be able to run your code. Once it comes to the lock part it will throw a exception and in the logs it will log just that - to change it to transactional.
Hazelcast
Next in line is Hazelast and their tutorial which can be found here.
Also pretty easy to use:
As with Ignite Hazelcast also provides you with a Java concurrency lock. Also as Ignite it provides much more then distributed locks and describing functionality of Hazelcast or Ignite can be a separate blog post, so I won’t go into it here.
Summary
On to the summary. If you want a solution based on ZooKeeper I would suggest Apache Helix. But if you don’t want to add ZooKeeper into your architecture I would recommend Ignite or Hazelcast. Which one depends on you. If you only plan to use to for distributed locks you can’t go wrong with each of them, but I if you need distributed locking perhaps you will need some other features in the future. So check what each offers and what best suits your current and perhaps your future needs.