分布式锁原理及使用

1、什么情况下需要使用到分布式锁

在单应用场景下,一般都会采用JDK的synchronized关键字修饰方法或者Lock锁(使用ReentrantLock实现同步,lock()方法:上锁,unlock()方法:释放锁,使用Condition实现等待/通知 类似于 wait()和notify()及notifyAll())的方式来解决多线程间的代码同步问题。因为这些多线程是运行在同一个JVM下的,但是随着用户量的增加,单应用服务没办法支撑起巨大的请求场景,这时候都会将单应用场景升级为分布式(多节点,多个JVM),这时候synchronized,Lock锁就没办法做到跨JVM的代码的同步执行。

2、分布式锁的实现方式

分布式锁可以通过以下三种方式实现:
1、基于缓存实现分布式锁
例如Redis、Memcache等等,缓存数据库的性能非常强,但是这种缓存数据库也有集群模式,也会产生数据的不同步。
2、基于Zookeeper实现分布式锁
Zookeeper的性能也是比较强大的,自身就是分布式集群,对于实现分布式锁更加可靠。
3、基于数据库层面实现分布式锁
数据库的性能本身就低,基于数据库实现,需要在每次处理数据时添加一条类似于锁的数据,来保证数据的可靠性
常见的方式有乐观锁和悲观锁

3、Zookeeper分布式锁的原理

Zookeeper分布式锁的原理如下:

1、客户端向Zookeeper发送请求获取锁,然后会在Zookeeper中的/lock节点下创建一个临时顺序的节点,如果有多个客户端请求相同的线程,则会同时在Zookeeper中创建多个子节点锁,并且节点都是顺序的,如/lock/1、/local/2、/local/3等等,依次类推,数字编号自动生成。

2、每个客户端都会获取/lock节点下所有创建的子节点(所有客户端创建的子节点锁),客户端获取到所有的子节点之后,开始比较子节点的顺序编号,顺序编号在这里就会起到决定性的作用,如果客户端发现自己创建的子节点顺序编号最小,那么就认为该客户端获取到了锁,使用完锁之后就会将节点删除。

3、如果客户端发现自己创建的子节点编号并不是所有子节点中最小的,那么就表示并没有获取到锁,此时客户端就需要找到比自己小的子节点,同时对这个节点进行事件监听,监听删除子节点的事件。

4、如果客户端从监听事件中得知比自己子节点编号小的节点被删除了,此时会再次判断自己的子节点编号是不是所有子节点中最小的,如果是,则获取到锁,如果不是则重复上步骤继续获取到比自己小的子节点并且监听事件信息。

客户端向Zookeeper获取锁时,为什么会创建一个临时的子节点?
因为临时顺序的节点特点就是当会话关闭后,自动将创建的节点删除,恰好可以满足使用完锁,就删除节点的理念,试想一下,如果我们使用的是持久化节点,那么当客户端1去获取锁处理数据的过程中挂掉了,那么在Zookeeper中创建的子节点/lock/1是不会被删除的,那么其他相同操作的客户端是无法获取锁的,就会导致数据处理异常,其他的客户端一直处于等待锁的状态,如果我们使用的是临时节点,即使客户端1在处理数据的过程中挂掉了,也就意味着会话断开了,一旦断开了会话,临时节点就会自动删除,相同的请求会向Zookeeper中再次请求一个新锁,然后去处理数据,数据处理完成后自动删除创建的锁。
临时节点就是为了防止客户端数据处理完之后锁不释放的问题。

顺序节点的作用?
用于所有客户端创建的子节点间进行比较,如果发现自己的子节点编号比较小,那么就获取锁。

原文链接:https://blog.csdn.net/weixin_44953658/article/details/131393784

4、.Zookeeper分布式锁的使用

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值