ZooKeeper锁服务

分布式锁概述

分布式锁在一组进程之间提供了一种互斥机制。在任何时刻,在任何时刻只有一个进程可以持有锁。分布式锁可以在大型分布式系统中实现领导者选举,在任何时间点,持有锁的那个进程就是系统的领导者。

(1)为了使用ZooKeeper来实现分布式锁服务,我们使用顺序znode来为那些竞争锁的进程强制排序。
①在锁znode下创建一个名为lock-的短暂顺序znode,并且记住它的实际路径名(create操作的返回值)。
②查询锁znode的子节点并且设置一个观察。
③如果步骤l中所创建的znode在步骤2中所返回的所有子节点中具有最小的顺序号,则获取到锁。退出。
④等待步骤2中所设观察的通知并且转到步骤2。

羊群效应

考虑有成百上千客户端的情况,所有的客户端都在尝试获得锁,每个客户端都会在锁znode上设置一个观察,用于捕捉子节点的变化。 每次锁被释放或另外一个进程开始申请获取锁的时候,观察都会被触发并且每个客户端都会收到一个通知。 “羊群效应“就是指大量客户端收到同一事件的通知,但实际上只有很少一部分需要处理这一事件。

在这种情况下,只有一个客户端会成功地获取锁,但是维护过程及向所有客户端发送观察事件会产生峰值流量,这会对ZooKeeper服务器造成压力。

解决方案:优化通知的条件
关键在于只有在前一个顺序号的子节点消失时才需要通知下一个客户端,而不是删除(或创建)任何子节点时都需要通知。
在我们的例子中,如果客户端创建了znode /leader/lock-1、/leader/lock-2和/leader/lock-3,那么只有当/leader/lock-2消失时才需要通知/leader/lock-3对照的客户端;/leader/lock-1消失或有新的znode /leader/lock-4加入时,不需要通知该客户端。

ZooKeeper实现共享锁

假设有这样一个场景:两台server :serverA,serverB需要在C机器上的/usr/local/a.txt文 件上进行写操作,如果两台机器同时写该文件,那么该文件的最终结果可能会产生乱序等问题。最先能想到的是serverA在写文件前告诉ServerB “我要开始写文件了,你先别写”,等待收到ServerB的确认回复后ServerA开始写文件,写完文件后再通知ServerB“我已经写完了”。假设 在我们场景中有100台机器呢,中间任意一台机器通信中断了又该如何处理?容错和性能问题呢?要能健壮,稳定,高可用并保持高性能,系统实现的复杂度比较 高,从头开发这样的系统代价也很大。接下来本文将介绍两种 ZooKeeper实现分布式共享锁的方法。

利用节点名称的唯一性来实现共享锁

ZooKeeper表面上的节点结构是一个和unix文件系统类似的小型的树状的目录结构,ZooKeeper机制规定:同一个目录下只能有一个唯一的文件名。

算法思路:利用名称唯一性,加锁操作时,只需要所有客户端一起创建/Leader/lock节点,只有一个创建成功,成功者获得锁。解锁时,只需删除/test/Lock节点,其余客户端再次进入竞争创建节点,直到所有客户端都获得锁。
在这里插入图片描述

利用顺序节点实现共享锁

算法思路:对于加锁操作,可以让所有客户端都去/lock目录下创建临时、顺序节点,如果创建的客户端发现自身创建节点序列号是/lock/目录下最小的节点,则获得锁。否则,监视比自己创建节点的序列号小的节点(当前序列在自己前面一个的节点),进入等待。解锁操作,只需要将自身创建的节点删除即可。

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值