浅聊一下分布式锁

分布式锁

在分布式系统下,不同的服务或者客户端都运行在各自的JVM进程下,多个服务共享同一份资源的话,那么就出问题了,本地的锁就没用了在这种情况之下。

分布式锁要保证有以下几点功能:

1.互斥性:任意时刻,只有一个线程能够拿到锁。

2.可重入:一个人拿到锁之后以后还可以再次的拿到锁。

3.高可用:如果哪个服务的释放锁的逻辑出现问题,就可能会导致锁没有释放。高可用就是保证了即使出现问题锁也要正常的释放。

说说分布式锁中的Redis分布式锁吧

Redis 分布式锁实现是用setnx这个,setnx是set if not exixts,set key value,如果key不存在就设置,存在就什么也不做。

释放锁直接del key 就释放锁了。

为了以防万一误删除其他的锁,可以使用lua脚本,它通过key对应的value来判断,lua脚本是原子性操作。

这样有什么问题没有?

答案是有的。如果在释放锁的时候服务挂掉了,那么锁就没有释放,其他服务的线程无法访问共享资源。—很大的一个问题。

解决这个问题可以在执行setnx命令的时候加上一个过期时间ex,到时间释放锁。

SET lockKey uniqueValue EX 3 NX

ex 过期时间

nx 如果当lockKey不存在的时候才能设置成功。

想一想,这样做还有什么问题没有?

答案依然是有的。

好像加上了一个过期数值解决了上述问题,根据设置过期时间数值的大小可以分为以下两种情况:

1.过期时间大于对共享资源操作的时间----->会影响性能,可以说占着茅坑不拉*。

2.过期时间小于对共享资源操作的时间----->导致分布式锁直接就失效了。

这怎么办呢?

可以用Redission,Redisson 是一个开源的 Java 语言 Redis 客户端,提供了很多开箱即用的功能,不仅仅包括多种分布式锁的实现。并且,Redisson 还支持 Redis 单机、Redis Sentinel 、Redis Cluster 等多种部署架构。

Redisson 看门狗自动续期

这其中有一个Watch Dog,看门狗,它的作用就是用来检测过期时间的,如果操作的线程还没有执行完的话,会不断的续期,进而保证锁不会因为执行超时被释放掉。

Watch Dog续费的原理就是上述提到的lua脚本,保证其原子性,默认是30秒的超市时间。

Redis 如何解决集群情况下分布式锁的可靠性?

在Redis集群下,由于Redis集群同步数据到各个结点是异步的,如果主节点刚获取到锁,他就挂了,因为主从之间有延迟,还没有同步到从节点, 此时新的 Redis 主节点依然可以获取锁,所以多个应用服务就可以同时获取到锁。

针对这个问题,Redis 之父 antirez 设计了 RedLock (红锁)来解决。

该算法的思想是客户端向Redis集群中的多个实例一次发送加锁的请求,在由半数以上的实例完成加锁的操作,就认为加锁成功,否则就加锁失败。

文章参考:https://javaguide.cn/distributed-system/distributed-lock

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值