数码资讯
详细setnxRedis命令实现了一个分布式锁的使用
选购提示
关注价格、性能、续航、售后和真实使用场景,理性比较后再下单。
分布式锁可以使用Redis的setnx命令实现的,和下面的实现方法。
对setnx命令简介
命令格式
setnx关键值
当没有键不存在时,键的值被设置为值。
如果一个给定的键已经存在,setnx不做任何动作。
setnx是速记,如果不存在。
返回值
返回整数,特别是
- 1,当设置键的值时
- 0,当键的值未设置时
例子
redis > setnx MyKey你好
(整数)1
redis > setnx MyKey你好
(整数)0
redis >得到钥匙
你好
redis >
使用setnx实现分布式锁
多个进程执行以下redis:
setnx lock.foo
如果setnx返回1,表示工艺获取一个锁,setnx设置密钥lock.foo价值锁的超时时间(当前时间+锁的有效时间)。
如果setnx返回0,其他进程已锁定,和进程不能进入临界区的进程不断在循环中得到setnx锁试运行。
解决僵局
考虑一个案件。如果这个过程被锁,它断开与redis连接(过程或许是悬挂或网络中断)。如果没有有效的释放机制,所有其他进程都处于等待状态,即出现死锁。
当我们使用setnx获得锁上面,我们设置的关键lock.foo价值锁的有效时间。进程获取锁后,其他进程将不断检测锁是否已过期。如果时间不在,等待过程也有机会得到锁。
然而,当锁是随着时间的推移,我们不能只是使用DEL命令删除的关键lock.foo释放锁。考虑以下,进程P1首先获得锁lock.foo,然后进程P1已经挂了。过程P2,P3是经常检查锁是否已被释放或出去的时候,和执行流程如下:
P2和P3的过程,阅读的关键lock.foo值检查是否锁了时间(通过比较当前时间和关键lock.foo判断是否超时的值)
P2和P3的过程发现,锁lock.foo已经离开时间
P2执行del lock.foo命令
P2执行setnx lock.foo命令并返回1,即P2被锁
P3执行删除命令删除lock.foo P2刚建立的关键lock.foo(这步是因为P3刚刚发现锁已经离开的时间)
P3执行setnx lock.foo命令并返回1,即P3被锁
P2和P3同时锁定。
从上面可以了解到,在检测到锁超时后,进程不能简单地执行del删除键操作来获取锁。
为了解决多个进程同时发生的问题,我们将看下面的算法。
我们假定进程P1首先获得锁lock.foo,然后进程P1已经挂断。以下:
1、过程执行setnx P4 lock.foo试图获得锁
2、由于进程P1被锁定,P4执行setnx lock.foo返回0,即得到锁失效
3、P4执行得到lock.foo检测锁是否已经走出来的时候,如果不暂停,等待一段时间,再次检查
4、如果P4发现锁已经离开的时间,即当前时间大于关键lock.foo价值,P4将执行以下操作
捷先lock.foo
5、为捷先操作设置键的值,它将返回旧值的关键。通过比较是否的关键lock.foo旧值小于当前时间,可以判断过程是否已被锁定。
6,如果另一个进程P5检测到锁超时之前P4执行捷先操作,然后P4的捷先操作返回一个时间戳大于当前时间,所以P4不会得到锁,继续等待。注意即使P4然后设置的关键lock.foo价值一比P5设置较大的值,但不影响价值。
此外,值得注意的是,该过程释放锁,这是之前,执行删除lock.foo操作之前,有必要判断锁是否已经第一时间。如果锁已经超时,锁可能被其他进程获得。然后删除lock.foo操作直接执行将导致其他进程已获得的锁释放。
程序代码
以下代码是用来使用的setnx命令作为一个分布式锁的算法实现。
lock_timeout = 3
锁= 0
lock_timeout = 0
lock_key = foo的锁定。
#获取锁
而锁!= 1:
现在= int(time.time())
lock_timeout =现在+ lock_timeout + 1
锁= redis_client.setnx(lock_key,lock_timeout)
如果锁或(= =现在1 > int(redis_client.get(lock_key))和(int)现在> redis_client.getset(lock_key,lock_timeout)):
打破
其他的:
(0.001)time.sleep
#已锁定
do_job()
#释放锁
现在= int(time.time())
如果现在的<< lock_timeout:
redis_client.delete(lock_key)
以上是本文的全部内容,希望能对您有所帮助,希望大家多多支持。
对setnx命令简介
命令格式
setnx关键值
当没有键不存在时,键的值被设置为值。
如果一个给定的键已经存在,setnx不做任何动作。
setnx是速记,如果不存在。
返回值
返回整数,特别是
- 1,当设置键的值时
- 0,当键的值未设置时
例子
redis > setnx MyKey你好
(整数)1
redis > setnx MyKey你好
(整数)0
redis >得到钥匙
你好
redis >
使用setnx实现分布式锁
多个进程执行以下redis:
setnx lock.foo
如果setnx返回1,表示工艺获取一个锁,setnx设置密钥lock.foo价值锁的超时时间(当前时间+锁的有效时间)。
如果setnx返回0,其他进程已锁定,和进程不能进入临界区的进程不断在循环中得到setnx锁试运行。
解决僵局
考虑一个案件。如果这个过程被锁,它断开与redis连接(过程或许是悬挂或网络中断)。如果没有有效的释放机制,所有其他进程都处于等待状态,即出现死锁。
当我们使用setnx获得锁上面,我们设置的关键lock.foo价值锁的有效时间。进程获取锁后,其他进程将不断检测锁是否已过期。如果时间不在,等待过程也有机会得到锁。
然而,当锁是随着时间的推移,我们不能只是使用DEL命令删除的关键lock.foo释放锁。考虑以下,进程P1首先获得锁lock.foo,然后进程P1已经挂了。过程P2,P3是经常检查锁是否已被释放或出去的时候,和执行流程如下:
P2和P3的过程,阅读的关键lock.foo值检查是否锁了时间(通过比较当前时间和关键lock.foo判断是否超时的值)
P2和P3的过程发现,锁lock.foo已经离开时间
P2执行del lock.foo命令
P2执行setnx lock.foo命令并返回1,即P2被锁
P3执行删除命令删除lock.foo P2刚建立的关键lock.foo(这步是因为P3刚刚发现锁已经离开的时间)
P3执行setnx lock.foo命令并返回1,即P3被锁
P2和P3同时锁定。
从上面可以了解到,在检测到锁超时后,进程不能简单地执行del删除键操作来获取锁。
为了解决多个进程同时发生的问题,我们将看下面的算法。
我们假定进程P1首先获得锁lock.foo,然后进程P1已经挂断。以下:
1、过程执行setnx P4 lock.foo试图获得锁
2、由于进程P1被锁定,P4执行setnx lock.foo返回0,即得到锁失效
3、P4执行得到lock.foo检测锁是否已经走出来的时候,如果不暂停,等待一段时间,再次检查
4、如果P4发现锁已经离开的时间,即当前时间大于关键lock.foo价值,P4将执行以下操作
捷先lock.foo
5、为捷先操作设置键的值,它将返回旧值的关键。通过比较是否的关键lock.foo旧值小于当前时间,可以判断过程是否已被锁定。
6,如果另一个进程P5检测到锁超时之前P4执行捷先操作,然后P4的捷先操作返回一个时间戳大于当前时间,所以P4不会得到锁,继续等待。注意即使P4然后设置的关键lock.foo价值一比P5设置较大的值,但不影响价值。
此外,值得注意的是,该过程释放锁,这是之前,执行删除lock.foo操作之前,有必要判断锁是否已经第一时间。如果锁已经超时,锁可能被其他进程获得。然后删除lock.foo操作直接执行将导致其他进程已获得的锁释放。
程序代码
以下代码是用来使用的setnx命令作为一个分布式锁的算法实现。
lock_timeout = 3
锁= 0
lock_timeout = 0
lock_key = foo的锁定。
#获取锁
而锁!= 1:
现在= int(time.time())
lock_timeout =现在+ lock_timeout + 1
锁= redis_client.setnx(lock_key,lock_timeout)
如果锁或(= =现在1 > int(redis_client.get(lock_key))和(int)现在> redis_client.getset(lock_key,lock_timeout)):
打破
其他的:
(0.001)time.sleep
#已锁定
do_job()
#释放锁
现在= int(time.time())
如果现在的<< lock_timeout:
redis_client.delete(lock_key)
以上是本文的全部内容,希望能对您有所帮助,希望大家多多支持。
声明:本文内容用于数码产品信息整理与选购参考,具体价格、库存、售后政策以官方渠道和电商页面实时信息为准。