Redis分布式锁的实现(纯文字)

Posted zhangrglearning

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Redis分布式锁的实现(纯文字)相关的知识,希望对你有一定的参考价值。

在使用Redis的分布式集群的时候,我们进行操作的时候需要对抢锁,也就是对线程的操作权限

我们在Redis中可以使用SetNX命令来进行锁争抢。

sexnx(Key,value),其中的key指的是锁的唯一标识,value姑且为1。

当锁抢成功,返回1则代表锁争抢成功。当然,我们接下来需要给锁一个有效时间,否则如果宕机的时候,进程挂掉,这个锁就一直不被释放,导致资源被占用。

所以我们可以设置过期时间expire(30).

有一个问题,因为争抢锁和设置过期时间的操作是分开的,所以在极端情况下,可能会出现抢到了锁,但是没有设置过期时间(在抢锁和设置过期时间之间服务器宕机)。也会发生资源一直被占用。

所以我们需要确保我们的抢锁和设置过期时间的操作是原子性的(其实就是transaction)。

所幸,我们可以使用set(key,value,expire,NX)来进行锁争抢。

锁的争抢完成了。那么我们在写代码的时候,有必要使用代码在任务完成之后删除当前锁。这就可能出现锁误删。

所以我们需要做判断,判断当前锁是否就是自己的那个线程中的锁。(保存线程ID可以使用抢锁时候的value)。

就是当线程A抢锁之后设置了30S的过期时间,但是他的任务用时可能45S,在30S的时候,锁过期了。线程B抢到了锁,在B执行的过程中,A任务执行完了,他就会删除锁,此时就会把B的锁删掉。这是不可以的。

但是这个不是原子性的。此时需要保证删除锁的操作也是原子性。

但是无论在什么情况下情况下,同一时间有多个线程在访问同样的代码块,这是我们不允许的。所以我们需要保证这个锁,要在任务时间内,不能被释放掉。所以我们需要开启一个守护线程。

开启一个守护线程,在我们的锁快要过期的时候,我们需要对锁进行续期,比如当剩下了1S的时候,我们可以再次设置过期时间为10S,一直循环往复。直到代码自己删除锁。

守护线程的实现是-->争抢到所以后,开启一个本地队列Task,去轮询这个Key(间隔N秒去检查这个Key的过期时间,然后根据需要去对锁进行续时),直到代码释放锁。

以上是关于Redis分布式锁的实现(纯文字)的主要内容,如果未能解决你的问题,请参考以下文章

Redis分布式锁的实现

Redis(十三):Redis分布式锁的正确实现方式

Redis中是如何实现分布式锁的?

Redis分布式锁的正确实现方式

Redis分布式锁的正确实现方式

Redis分布式锁的正确实现方式