zookeeper分布式锁
使用zk实现分布式锁之前,先来看下zk的特性
1.数据结构
存储方式为key-value,类似于文件目录结构
- /lock
- /a
- /b
- /c
有一个根结点,根结点下面是对应一个或多个节点 树的结构
2.节点的特性
- 有序性,
- 临时节点,
- 永久节点
3.watch机制
在zk中,可以节点设置监听,来监听节点的一些变化,然后触发操作
绑定监听: getData exists getChilden 触发监听:create,delete, setData
查询操作可以绑定监听,增删改操作可以绑定监听,且监听是一次性的,在出发一次会消失,可以循环绑定来达到一直监听的效果.
分布式锁方案
1.获取锁:利用在同级目录下,不能创建相同的节点的特性,可以利用多线程去创建一个节点,但是只能有一个线程可以创建成功, 所以也只有创建成功的线程获得到了锁.(通过创建临时序列节点,找出最小的序列节点,获取分布式锁,程序执行完成之后此序列节点消失,通过watch来监听节点的变化,当节点变化时-删除时,剩下的最小的序号节点,获取锁,程序执行,执行完成然后在释放锁,最小的节点序号获取到锁….) 2.释放锁:通过删除节点来释放锁,来触发刚才没有获取到锁的线程的监听,让他们再次来竞争获取锁.
锁需要考虑的特性
- 锁的互斥性:同样的节点只能有一个创建成功.
- 锁的重入行:锁节点的值,判断是否为同一个线程,同线程锁重入值+1
因为zk节点唯一的,不能重复,节点类型为临时节点, 一台zk服务器创建成功时候,另外的zk服务器创建节点时候就会报错,该节点已经存在。这时候其他的zk服务器就会开始监听并等待。让这台zk服务器的程序现在执行完毕,释放锁。关闭当前会话。临时节点就会消失,并且事件通知Watcher,其他的就会来创建