画分布式锁之Zookeeper实现机制

      Zookeeper,是为我们熟知的一款开源的分布式应用程序协调服务,很多动物命名的项目都是通过Zookeeper做集群管理的,也被大家认可为动物园管理员,Zookeeper可以做很多事情,集群管理,数据发布/订阅,配置维护,服务注册与发现,分布式同步,分布式队列,还有就是本文要去探索的分布式锁功能。

      基于Zookeeper去实现分布式锁,有着他天生的优势,这一点,我们之前讲的基于redis的Redisson【万剑归宗之七剑下天山,redisson的百锁解构(下) 】框架实现的分布式锁可靠性上是比不上他的。Zookeepert提供多层级的节点命名空间(ZNode),我们可以通过他的一些特有的定义去实现分布式锁,

2062223-834ceb7e2e7a5b6f

1,临时节点 (Ephemeral Node),客户端可以创建一个临时节点,在会话结束或者会话超时的时候,自动删除该节点。

2062223-c3e7de433f1589a5

2,有序节点(Sequential Node),如上图所示,在locks节点下面创建了三个有序的节点,我们也可以以locks-node-1,2,3这样子来创建节点,对于图中的三个节点是一个临时有序的节点。

2062223-d1c83ad9e39fe34f

3,事件监听(watcher) 客户端可以对某个节点添加监听器,可以对节点设置事件监听,当节点数据或者结构发生变化的时候,就会通知监听的客户端,有以下四个事件,(1) 节点创建 ,(2) 节点删除,(3) 节点数据修改,(4) 子节点变更。

基于以上几个基本的定义,我们可以来阐述一下Zookeeper实现分布式锁的算法流程。

    1,客户端A过来获取锁,首先,【create】,在zookeeper的持久节点locks下创建一个顺序临时节点/locks/_c_dd8ff0a4-0064-4756-9ec0-cf2911479217-lock-0000000001;

    2,调用【getChildren(watch=false)】,获取locks节点下的子节点列表childList;

    3,从这个列表childList中,判断自己创建的节点序号是否是最小的,如果是最小的,就说明获取锁成功啦,返回true;

    4,如果步骤3中判断自己不是序号最小的节点序号,就从childList中获取到自己前一位childList(index-1)的节点,调用【exists(watch=true)】,这样子就是给自己前一个节点设置了监听,一旦前一个节点发生变化,就会通知给监听器。

    5,步骤4中如果【exists(watch=true)】返回的是false,就返回步骤2

    6,步骤4中如果【exists(watch=true)】返回的是true,等到设置的监听器接收到通知,再去执行步骤2,直到获得锁成功。

2062223-75a6cc3f9b1193e7

    再简单普及下zookeeper的事件监听有哪些,主要有以下几个:

EventType.None                        连接zookeeper成功

EventType.NodeCreated            节点创建

EventType.NodeDataChanged  节点数据更新

EventType.NodeDataChanged  子节点变更

EventType.NodeDeleted            节点删除

      到这里,就把zookeeper实现分布式锁的机制讲解清楚了,接下来就是通过代码去实践zookeeper的分布式锁,这块如果是我们自己去写的,也是按照上面的逻辑去进行封装,万幸,业界有一款牛逼炸的框架curator,此框架实现了zookeeper几大核心功能,也完美实现了分布式锁,和redisson一样,也对各种不同的锁做了相应的实现,接下来我们会去分析这一款框架。目前感冒中,如果文章中有逻辑错误的,欢迎留言指正,谢谢大家观看。

猜你喜欢

转载自blog.csdn.net/weixin_34406086/article/details/87584767
今日推荐