- 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!
- C++案例趣學
- Vue.js 2 and Bootstrap 4 Web Development
- Reactive Programming with Swift
- Rust編程從入門到實戰
- 從程序員到架構師:大數據量、緩存、高并發、微服務、多團隊協同等核心場景實戰
- Java程序設計與計算思維
- HTML5游戲開發案例教程
- AutoCAD VBA參數化繪圖程序開發與實戰編碼
- Ext JS 4 Web Application Development Cookbook
- MongoDB權威指南(第3版)
- Responsive Web Design by Example
- Python圖形化編程(微課版)
- Web前端應用開發技術
- JavaScript悟道
- 分布式數據庫HBase案例教程