- Getting Started with Hazelcast(Second Edition)
- Mat Johns
- 618字
- 2021-07-16 13:14:36
Distributed locking
When building a broad, horizontally scaled application, one aspect that we tend to lose is the ability to restrict and prevent concurrent activity across the whole application. Within a single JVM, we use a synchronized lock to guard a section of functionality from a concurrent execution. Once we move away from a single JVM, this problem becomes a much bigger issue. Traditional approaches would leverage a transactional database to provide a system for locking in the form of a table rowlock or a transactional state. However, this approach presents us with a single point of failure and contention issues when scaling up our application.
Hazelcast offers a distributed locking facility, allowing us to attempt acquiring a cluster-wide named lock, and guard the functionality behind it. If we can create an example class LockingExample
, we can demonstrate this ability, as follows:
public class LockingExample { public static void main(String[] args) throws Exception { HazelcastInstance hz = Hazelcast.newHazelcastInstance(); Lock lock = hz.getLock("theTime"); while (true) { if (lock.tryLock(30, TimeUnit.SECONDS)) { try { while (true) { System.err.println(new Date()); Thread.sleep(1000); } } finally { lock.unlock(); } } } } }
When considering the preceding code, we are continuously attempting to acquire the theTime
lock. Should we be successful in acquiring the lock, we shall continuously start printing out the time every second. If we run the class once, we will see the behavior as described:
Members [1] { Member [127.0.0.1]:5701 this } Thu Jan 01 00:00:00 UTC 2015 Thu Jan 01 00:00:01 UTC 2015 Thu Jan 01 00:00:02 UTC 2015 Thu Jan 01 00:00:03 UTC 2015
However, if we start running the example multiple times, we enable the resilience of the locked section in that, the multiple nodes are all continuously trying to enter the block of code but are prevented by the acquired lock of another running instance. This is where the locking capability provided by Hazelcast shows its strength. If we were to start killing off nodes, especially the ones currently holding the lock, we fail-safe. By killing the nodes that are not holding the lock, the correct behavior is still enforced. However, if we kill off the node that is currently holding the lock, it will be automatically released, as the owner is now dead. At this point, another node can now acquire the lock and take over the responsibility of telling us the time.
Using this capability, we have provided the application with the ability to have a resilient, but exclusive, execution task that exists within the cluster. Where this task actually occurs isn't particularly controllable, but assuming that the nodes are present, it is guaranteed to run somewhere, but only once.
Tactical locking
In addition to a single, blunt gatekeeper locking where we effectively prevent concurrent execution across the entire cluster for a specific type of activity, we might want to lock on a more specific context. Rather than using a Lock
object, IMap
provides us with entry locking capabilities. Using this, we can acquire a mutex on a specific entry, enabling the ability to prevent concurrent modifications on a targeted piece of data, as follows:
public class MapLockingExample { public static void main(String[] args) { HazelcastInstance hz = Hazelcast.newHazelcastInstance(); IMap<String, Date> arrivals = hz.getMap("arrivals"); if (arrivals.tryLock("London")) { try { arrivals.put("London", new Date()); } finally { arrivals.unlock("London"); } } System.err.println("London: " + arrivals.get("London")); } }
While we have explicitly acquired, processed, and reliably released the lock, this gives us an absolute control over the amount of blocking that we might be introducing into our application. If used wisely, this is a very powerful tool.
Note
It is probably always the best choice to use locks with a defined time, as without this, the threads will block indefinitely!
- Python程序設(shè)計(第3版)
- Learning ASP.NET Core 2.0
- Practical DevOps
- Building Mobile Applications Using Kendo UI Mobile and ASP.NET Web API
- 手把手教你學C語言
- Learning Zurb Foundation
- Mastering JavaScript High Performance
- Go語言精進之路:從新手到高手的編程思想、方法和技巧(1)
- OpenGL Data Visualization Cookbook
- 用戶體驗可視化指南
- 深入剖析Java虛擬機:源碼剖析與實例詳解(基礎(chǔ)卷)
- Hands-On Full Stack Development with Spring Boot 2.0 and React
- Unity 3D腳本編程:使用C#語言開發(fā)跨平臺游戲
- Go語言底層原理剖析
- 計算機應用基礎(chǔ)