zookeeper分布式锁
zookeeper是一个为分布式应用提供一致性服务的软件,它内部是一个分层的文件系统目录树结构,规定统一个目录下只能有一个唯一文件名
数据模型
- 永久节点
节点创建后,不会因为会话失效而消失 - 临时节点
与永久节点相反,如果客户端连接失效,则立即删除节点 - 顺序节点
与上述两个节点特性类似,如果指定创建这类节点时,zk会自动在节点名后加一个数字后缀,并且是有序的
##监视器(watcher):
当创建一个节点时,可以注册一个该节点的监视器,当节点状态发生改变时,watch被触发时,ZooKeeper将会向客户端发送且仅发送一条通知,因为watch只能被触发一次
根据zookeeper的这些特性来实现分布式锁
创建一个锁目录lock
希望获得锁的线程A就在lock目录下,创建临时顺序节点
获取锁目录下所有的子节点,然后获取比自己小的兄弟节点,如果不存在,则说明当前线程顺序号最小,获得锁
线程B获取所有节点,判断自己不是最小节点,设置监听(watcher)比自己次小的节点(只关注比自己次小的节点是为了防止发生“羊群效应”)
线程A处理完,删除自己的节点,线程B监听到变更事件,判断自己是最小的节点,获得锁。
小结
在分布式系统中,共享资源互斥访问问题非常普遍,而针对访问共享资源的互斥问题,常用的解决方案就是使用分布式锁,这里只介绍了几种常用的分布式锁,分布式锁的实现方式还有有很多种,根据业务选择合适的分布式锁
下面对上述几种锁进行一下比较:
数据库锁
优点:直接使用数据库,使用简单。
缺点:分布式系统大多数瓶颈都在数据库,使用数据库锁会增加数据库负担。
缓存锁
优点:性能高,实现起来较为方便,在允许偶发的锁失效情况,不影响系统正常使用,建议采用缓存锁。
缺点:通过锁超时机制不是十分可靠,当线程获得锁后,处理时间过长导致锁超时,就失效了锁的作用。
zookeeper锁
优点:不依靠超时时间释放锁;可靠性高;系统要求高可靠性时,建议采用zookeeper锁。
缺点:性能比不上缓存锁,因为要频繁的创建节点删除节点。