zookeeper分布式锁 -- 读锁和写锁实现方式
读锁和写锁
读锁: 是共享锁,读锁与读锁是可以兼容的,所以同时有多个请求都可以持有
写锁: 是独占锁,写锁与任何锁都互斥,所以只有一个请求持有,这个请求释放写锁其他请求才能持有
一旦持有写锁,说明数据在发送变化就不能读了,自然一个请求就不能出现读锁和写锁共存的情况
总结: 读锁与读锁之间兼容,其他都是互斥
读写锁的实现逻辑转换如下
读锁: 请求要判断是否可以持有共享资源的读锁,需要判断之前是否有请求持有这个共享资源的写锁
写锁: 请求要判断是否可以持有写锁,需要判断是否有请求持有这个共享资源的读锁或者写锁,就是没有请求持有这个共享资源的任何的锁
zookeeper区分分布式锁
区分是那个共享资源的锁,是通过zookeeper路径来区分的
区分一个共享资源是读锁还是写锁这种锁的类型,是通过zookeeper节点名的前缀来区分的
zookeeper实现分布式写锁
1、请求过来的时候都会创建一个临时序号节点
2、获取zookeeper中所有的临时序号节点
3、判断自己是否是最小的节点
如果是,说明在这个请求之前是没有其他请求获取并持有这个共享资源的读锁或者写锁,目前共享资源访问的第一个请求,我可以获取并持有这个共享资源的写锁
如果不是,说明已经有请求在我之前获取并持有这个共享资源的写锁或者读锁了,前面有请求获取到写锁或者读锁,我都互斥,自然就获取写锁失败
获取锁失败之后,监听最小的临时序号节点,如果最小的临时序号节点出现变化,则回到第二步进行执行
zookeeper实现分布式读锁
1、请求过来的时候都会创建一个临时序号节点
2、获取到zookeeper中比自己序号小的所有临时节点
3、判断最小节点是否为读锁(根据写锁的实现原理可知,如果写锁存在,必然是最小临时序号节点)
如果是读锁,说明这个共享资源目前没有请求持有写锁,直接获取并持有读锁
如果不是读锁,说明目前第一个请求持有写锁,读锁写锁互斥,获取并持有读锁失败
获取读锁失败之后,监听最小的临时序号节点,如果最小的临时序号节点出现变化,则回到第二步进行执行