分布式锁的实现方案:使用zookeeper和redis的好处

4 篇文章 0 订阅
2 篇文章 0 订阅

1. 分布式锁的应用场景有哪些呢:

定时任务,秒杀,流量控制

1.定时任务:

一般不会使用分布式锁

2.秒杀抢购:

防止库存超卖的问题

3.双写一致性:

更新db,更新reddis

2. 分布式锁的实现方案:

1.基于数据库实现--mysql行锁实现

2.基于zookeeper实现--cp模式

3.基于reddix实现--ap模式

4.redis框架--redission,redisLock

要求:保持一致性,zk实现分布式锁

要求:保证可用性,redis实现分布式锁

主要使用zookeeper和redis,redis中有一个红锁的概念

但是实际生产中,不会使用分布式锁来保持接口的幂等性,因为实际生产中会有很多集群,同时抢一把锁,不太可能用它去实现,所以会使用zookeeper来实现分布式锁。

3. zookeeper实现分布式锁

zookeeper 实现分布式锁原理:

zookeeper 节点路径不能重复,保持唯一性

临时节点+事件通知

1.获取锁的方法:
多个 jvm 同时在 zk 上创建一个相同的临时节点/lockPath,最终只能够有一个jvm 创建临时节点成功,如果能够创建临时节点成功 jvm 表示获取锁成功能够正常执行业务逻辑,如果没有创建临时节点成功的 jvm,则表示获取锁失败。获取锁失败之后,可以采用不断重试策略,重试多次获取锁失败之后,当前的 jvm 就进入到阻塞状态。

2.释放锁方法:
直接调用.close(;释放锁因为采用临时节点,当我们调用 close0方法的时候该临时节点会自动被删除。
其他没有获取到锁的 jvm,就会从新进入到获取锁的状态。

3.被唤醒的方法:
被阻塞的 jvm(没有获取锁成功的 jvm),采用事件监听的方式监听到节点已经被删除的情况下,则开始从新进入到获取锁的状态。

基于临时节点实现:

分布式锁实现方案1多个jvm同时创建一个临时节点:羊群效应

解释以上3步:

jvm会在zookeeper上创建一个临时节点,在zookeeper上路径不允许重复,保持了维性,创建了一个相同的临时节点,所以最后只有一个临时节点可以创建成功,可以执行我们业务逻辑的代码。jvm抢我们的分布式锁后,创建临时节点成功后,其他的jvm创建临时节点就失败了,而创建失败的临时节点会阻塞还是重试,实际情况上会进行重试。因为如果jvm创建临时节点成功后,表示获取成功,如果将业务代码快速执行完毕,再调用close直接关闭,所以在zk上进行删除,其他的jvm可以通过订阅节点,一旦被删除,zkshell端就会通知其他jvm已经被执行,但是剩下的jvm会重新被唤醒,做竞争锁。所以不可以在一个jvm执行创建临时节点成功后,直接让其他jvm阻塞。以后的唤醒成本会非常高,所以让jvm01创建成功后,其他jvm重试多次失败后,再让其他jvm阻塞。

怎么释放锁:

直接调用close

4. zookeeper实现分布式锁,当业务超时时,一直不释放锁应该如何处理?

可以采用续命设计,续命多次如果业务还是没有执行完毕的情况下,则认为该锁超时,应该主动释放锁,防止其他jvm一直阻塞等待,再将业务代码全部回滚。

如何回滚:使用手动事务

具体措施:设定一个超时时间,比如:90s

5. Zookeeper,如何避分布式锁羊群效应问题?

什么是羊群效应?
当 jvm 释放锁的时候,会唤醒正在等待的 jvm 从新进入到获取锁的状态。如果正在阻塞的等待获取锁的 jvm,如果有几十个或者几百个、上千个的情况下ZkServer 端唤醒所有正在等待的 vm,从新进入到获取锁的状态,唤醒的成本是非常高有可能会造成我们 ZkServer 端阻塞。

好了,今天就分享到这里,喜欢的一键三连!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值