基于zookeeper 实现分布式读写锁
分布式锁
如果不同的系统或一个系统的不同主机共享了一组资源,那么访问这些资源的时候,就需要通过一些互斥的手段来防止彼此之间的干扰,以保证一致性,在这种情况下,就需要使用分布式锁了。
读写锁
读写锁是同一时刻可以允许多个读操作访问,但是在写操作访问时,所有的读操作和其他写操作均被阻塞。Java 并发包提供的读写锁实现是ReentantReadWriteLock
。
分布式读写锁思路
下面我们介绍基于zookeeper 如何实现分布式读写锁:
如何定义锁节点:
通过zookeeper 上的数据节点来表示一个锁,比如:/lock/请求类型-顺序号。这个节点是临时节点,其后的序号由zookeeper 顺序生成,代表zookeeper 节点的全局唯一顺序,例如/lock/READ-00000001 就表示一个类型为读的分布式锁。zookeeper 节点结构如下:
如何获取锁:
在获取锁时,客户端到/lock 节点下创建一个临时顺序节点,如果是读,就创建一个形如/lock/READ- 的临时顺序节点,然后zookeeper 会返回一个完整的节点,形如/lock/READ-00000002 的带有顺序号的临时节点,这个节点就代表着你将要获取的锁。
判断是否得到锁:
如果是写锁:
- 获取/lock 下的子节点
- 按照顺序号排序
- 检查此写锁之前是否还有其他锁,若有先注册对该写锁前一个锁的监听,然后阻塞该写锁获取,若监听到该写锁前一个锁已释放,则该写锁打开阻塞。
如果是读锁:
- 获取/lock 下的子节点
- 按照顺序号排序
- 检查此读锁之前是否有写锁,若有先注册对该读锁的前一个写锁的监听,然后阻塞该读锁的获取。若监听到该读锁前一个写锁已释放,则该读锁打开阻塞。
分布式读写锁代码实现
public final class DLock
{
private ZkClient zkClient;
priva