什么是分布式协调服务,什么是分布式锁

1、什么是分布式协调服务

分布式协调技术主要用来解决分布式环境当中的多个进程之间的同步控制,让他们有序的去访问某种临界资源,防止造成脏数据的后果
在这里插入图片描述

2、什么是分布式锁

为了防止分布式系统中的多个进程之间相互干扰,需要一种分布式协调技术来对这些进程进行调度,而这个分布式协调技术的核心就是实现分布式锁。

2.1、分布式锁应该具备哪些条件

  • 分布式系统环境下,一个方法在同一时间只能被一个机器的一个线程执行
  • 高可用的获取锁和释放锁(一直可以获取锁,一直可以释放锁 )
  • 高性能的获取锁和释放锁(获取锁和释放锁的速度一定要快)
  • 具备可重入特性(可以理解为重新进入,有多个任务并发使用,而不用担心数据错误)
  • 具备锁失效机制,防止死锁(为了防止一些在获取锁后服务突然崩溃,而释放不了锁的情况)
  • 具备非阻塞锁特性,即没有获取到锁,将直接返回获取锁失败

2.2、分布式锁的实现有哪些

  • Redis:利用redis的setnx命令,此命令是原子性操作,只有当key不存在的时候,才可以set成功,也就相当于添加了锁
  • Zookeeper:利用zookeeper的顺序临时节点,来实现分布式锁和等待队列,zookeeper设计的初衷,就是为实现分布式锁服务的。

2.3、 通过Redis实现分布式锁的过程和原理

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2.3、 通过Zookeeper实现分布式锁的过程和原理

2.3.1、什么是Zookeeper

zookeeper是一种分布式协调服务,用于管理大型主机,在分布式环境中协调和管理服务是一个复杂的过程,zookeeper通过其简单的架构和API解决了这个问题,zookeeper允许开发人员专注于核心应用程序逻辑,而不用担心应用程序的分布式特性(比如像redis的加锁,解锁和锁超时等步骤)。

2.3.1、Zookeeper的数据模型

zookeeper是一个树型的目录服务,zookeeper的数据存储基于节点,这种节点叫Znode,Znode的引用方式是路径引用,类似于文件路径,比如下图中的 /动物/猫,这样的层级结构,让每一个Znode节点拥有唯一的路径,就像命名空间一样对不同的信息作出清晰的隔离。模型如下图所示:
在这里插入图片描述

2.3.2、Znode包含哪些元素

在这里插入图片描述

  • data:Znode存储的数据信息
  • ACL:记录Znode的访问权限,即哪些人或哪些IP可以访问本节点
  • stat:包含Znode的各种元数据(数据的数据,比如数据的时间、大小等等),比如事务ID、版本号、时间戳、大小等。
  • child:当前节点的子节点引用

注意:Zookeeper是为读多写少的场景所设计,Znode并不是用来存储大规模的业务数据,而是用于存储少量的状态和配置信息,每个节点的数据最大不能超过1MB。

2.3.3 Zookeeper的基本操作

创建节点:create
删除节点:delete
判断节点是否存在:exists
获得一个节点的数据:getData
设置一个节点的数据:setData
获取节点下的所有子节点:getChildren
其中,exists、getData、setData属于读操作,Zookeeper客户端在请求读操作的时候,可以选择是否选择Watch(观察),也就是因为这,Zookeeper本身就具备观察者模式。

2.3.4、Zookeeper的事件通知

我们可以把Watch理解成是注册在Znode上的触发器,当这个Znode发生改变,也就是调用了create、delete和setData方法的时候,将会触发Znode上注册的对应事件,请求Watch的客户端会接收到异步通知。
客户端调用getData方法,Watch参数是true,服务端接到请求,返回节点数据,并且在对应的哈希表里插入被Watch的Znode路径,以及Watch列表
在这里插入图片描述
当被Watch的Znode已删除,服务端会查找哈希表,找到该Znode对应的所有Watcher,异步通知客户端,并且删除哈希表中对应的key-value
在这里插入图片描述
在这里插入图片描述

2.3.5、Zookeeper实现分布式锁

什么是临时顺序节点?
Znode分为四种类型:

  • 持久节点 (PERSISTENT) 默认的节点类型。创建节点的客户端与zookeeper断开连接后,该节点依旧存在 。
  • 持久节点顺序节点(PERSISTENT_SEQUENTIAL)
    所谓顺序节点,就是在创建节点时,Zookeeper根据创建的时间顺序给该节点名称进行编号:
  • 临时节点(EPHEMERAL) 和持久节点相反,当创建节点的客户端与zookeeper断开连接后,临时节点会被删除:
  • 临时顺序节点(EPHEMERAL_SEQUENTIAL)
    顾名思义,临时顺序节点结合和临时节点和顺序节点的特点:在创建节点时,Zookeeper根据创建的时间顺序给该节点名称进行编号;当创建节点的客户端与zookeeper断开连接后,临时节点会被删除。

Zookeeper分布式锁恰恰应用了临时顺序节点。详细步骤如下:
首先,在Zookeeper当中创建一个持久节点ParentLock。当第一个客户端想要获得锁时,需要在ParentLock这个节点下面创建一个临时顺序节点 Lock1。
之后,Client1查找ParentLock下面所有的临时顺序节点并排序,判断自己所创建的节点Lock1是不是顺序最靠前的一个。如果是第一个节点,则成功获得锁。
这时候,如果再有一个客户端 Client2 前来获取锁,则在ParentLock下载再创建一个临时顺序节点Lock2。Client2查找ParentLock下面所有的临时顺序节点并排序,判断自己所创建的节点Lock2是不是顺序最靠前的一个,结果发现节点Lock2并不是最小的。于是,Client2向排序仅比它靠前的节点Lock1注册Watcher,用于监听Lock1节点是否存在。这意味着Client2抢锁失败,进入了等待状态。
这时候,如果又有一个客户端Client3前来获取锁,则在ParentLock下载再创建一个临时顺序节点Lock3。Client3查找ParentLock下面所有的临时顺序节点并排序,判断自己所创建的节点Lock3是不是顺序最靠前的一个,结果同样发现节点Lock3并不是最小的。
于是,Client3向排序仅比它靠前的节点Lock2注册Watcher,用于监听Lock2节点是否存在。这意味着Client3同样抢锁失败,进入了等待状态
这样一来,Client1得到了锁,Client2监听了Lock1,Client3监听了Lock2。这恰恰形成了一个等待队列,很像是Java当中ReentrantLock所依赖的AQS(AbstractQueuedSynchronizer)。
在这里插入图片描述

2.3.6、redis锁与zookeeper锁的区别:

Redis分布式锁,需要自己不断去尝试获取锁,比较消耗性能
ZooKeeper分布式锁,获取不到锁,注册个监听器即可,不需要不断主动尝试获取锁,性能开销较小
如果Redis获取锁的那个客户端挂了,那么只能等待超时时间之后才能释放锁
而对于ZooKeeper,因为创建的是临时znode,只要客户端挂了,znode就没了,此时就自动释放锁

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值