one, exclusive lock and shared lock
Distributed locks are a way to control the simultaneous access of shared resources between distributed systems. Divided into exclusive and shared locks.
Exclusive Lock
An exclusive lock (Exclusive Locks, abbreviated as X-lock), also known as a write lock or exclusive lock, is a basic type of lock. If the transaction T1 adds an exclusive lock to the data object O1, only the transaction T1 is allowed to read and update the O1 during the entire lock-up, and no other transaction can perform any type of operation on the data object-until T1 releases the exclusive lock.
Shared Locks
Shared Locks, or S-locks, also known as read locks. Allows a resource to be accessed by multiple read operations, or accessed by a write operation, but not both. (the definition of shared lock in section 6.17 of the Principles and practices of distributed consistency from Paxos to zookeeper is not strictly described, so it is not referenced).
The book's description of how to use zookeeper for exclusive and shared locks is clear and understandable.
For implementing an exclusive lock, it is simply that multiple clients compete to create the same temporary child node at the same time, zookeeper can ensure that only one client is created successfully, then this successful client acquires an exclusive lock. Normally, the client executes the business logic to delete the node, which is to release the lock. If the client goes down, the temporary node is automatically deleted and the lock is freed.
The flowchart is as follows:
For shared locks, it's a bit cumbersome because it involves a read or write operation. All clients will go to a node, for example:/shared_lock Create a temporary order node, if it is a read request, will create a node such as/shared_lock/192.168.0.1-r-0000000001, if it is a write operation, create such as/ The shared_lock/192.168.0.1-w-0000000001 node. Whether to acquire a shared lock, judging from the following four steps:
1, after the node is created, gets all the child nodes under the/shared_lock node and watcher listens to the node to register the child node changes.
2. Determine the order of your own node ordinal in all child nodes.
3. For read requests:
If there is no child node that is smaller than its ordinal number, or if all child nodes that are smaller than their ordinal are requested, then it indicates that they have successfully acquired the shared lock and begin to execute the read logic.
If there is a write request in a child node that is smaller than its ordinal number, you need to wait.
For write requests:
If you are not the sub-node with the smallest ordinal number, then you need to go to wait.
4, after receiving the watcher notification, repeat step 1.
The flowchart is as follows:
Second, the curator realization of exclusive lock
Basic excerpt from the sample code on the book:
Package com.my.CuratorTest;
Import Org.apache.curator.framework.CuratorFramework;
Import Org.apache.curator.framework.CuratorFrameworkFactory;
Import Org.apache.curator.framework.recipes.locks.InterProcessReadWriteLock;
Import Org.apache.curator.retry.ExponentialBackoffRetry;
Import Java.util.concurrent.CountDownLatch; /** * Title: <br/> * Intention: <br/> * <p> * Class NAME:COM.MY.CURATORTEST.RECIPESSHAREDLOCKTEST&L t;br/> * Create date:2017/8/20 17:07 <br/> * Project name:mytest <br/> * company:all Rights Reserved . <br/> * copyright©2017 <br/> * </p> * <p> * Author:gaowei <br/> * 1st_examiner: < br/> * 2nd_examiner: <br/> * </p> * * @version 1.0 * @since JDK 1.7 */public class Recipessharedlock
Test {static String Lockpath = "/curator_recipes_lock_path"; static Curatorframework client = Curatorframeworkfactory.builder (). ConnectString ("127.0.0.1:2181"). Retrypolicy (nEW Exponentialbackoffretry (3)). Build ();
static int data = 1;
public static void Main (string[] args) {Client.start ();
Final Interprocessreadwritelock lock = new Interprocessreadwritelock (client, Lockpath);
Final Countdownlatch down = new Countdownlatch (1);
for (int i= 0;i< 30;i++) {final int k = i; New Thread (New Runnable () {@Override public void run () {if (k%2 = = 0) {try {Down.countdown ()}
;
Lock.readlock (). acquire ();
System.out.println (System.nanotime () + "," + Thread.CurrentThread (). GetName () + "get to read lock, current data =" + "+ data";
Lock.readlock (). Release ();
} catch (Exception e) {e.printstacktrace ();
}} else {try {down.countdown ();
Lock.writelock (). acquire ();
Data + +;
System.out.println (System.nanotime () + "," + Thread.CurrentThread (). GetName () + "Get to write lock, write success, current data =" + data);
Lock.writelock (). Release (); } catch (Exception e) {E.printstackTrace ();
}}}). Start ();
} down.countdown (); }
}
Third, the curator realization of shared lock
Package com.my.CuratorTest;
Import Org.apache.curator.framework.CuratorFramework;
Import Org.apache.curator.framework.CuratorFrameworkFactory;
Import Org.apache.curator.framework.recipes.locks.InterProcessReadWriteLock;
Import Org.apache.curator.retry.ExponentialBackoffRetry;
Import Java.util.concurrent.CountDownLatch; /** * Title: <br/> * Intention: <br/> * <p> * Class NAME:COM.MY.CURATORTEST.RECIPESSHAREDLOCKTEST&L t;br/> * Create date:2017/8/20 17:07 <br/> * Project name:mytest <br/> * company:all Rights Reserved . <br/> * copyright©2017 <br/> * </p> * <p> * Author:gaowei <br/> * 1st_examiner: < br/> * 2nd_examiner: <br/> * </p> * * @version 1.0 * @since JDK 1.7 */public class Recipessharedlock
Test {static String Lockpath = "/curator_recipes_lock_path"; static Curatorframework client = Curatorframeworkfactory.builder (). ConnectString ("127.0.0.1:2181"). Retrypolicy (nEW Exponentialbackoffretry (3)). Build ();
static int data = 1;
public static void Main (string[] args) {Client.start ();
Final Interprocessreadwritelock lock = new Interprocessreadwritelock (client, Lockpath);
Final Countdownlatch down = new Countdownlatch (1);
for (int i= 0;i< 30;i++) {final int k = i; New Thread (New Runnable () {@Override public void run () {if (k%2 = = 0) {try {Down.countdown ()}
;
Lock.readlock (). acquire ();
System.out.println (System.nanotime () + "," + Thread.CurrentThread (). GetName () + "get to read lock, current data =" + "+ data";
Lock.readlock (). Release ();
} catch (Exception e) {e.printstacktrace ();
}} else {try {down.countdown ();
Lock.writelock (). acquire ();
Data + +;
System.out.println (System.nanotime () + "," + Thread.CurrentThread (). GetName () + "Get to write lock, write success, current data =" + data);
Lock.writelock (). Release (); } catch (Exception e) {E.printstackTrace ();
}}}). Start ();
} down.countdown (); }
}
Reference:
1, from Paxos to zookeeper distributed consistency principle and practice