美文网首页
python实现基于redis的分布式锁

python实现基于redis的分布式锁

作者: elroyGuo | 来源:发表于2019-04-17 22:34 被阅读0次

    可靠性

    为了确保分布式锁可用,至少需要确保锁的实现同时满足以下四个条件:

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

    2.不会发生死锁。当一个线程持有锁的期间崩溃而没有主动解锁,要保证其他线程能加锁。

    3.具有容错性。只要大部分的redis结点正常运行,线程就可以加锁和解锁。

    4.解铃还须系铃人。加锁和解锁必须是同一个线程,当前线程不能解其他线程的锁。

    代码实现

    加锁代码

    可以看到,我们加锁就一行代码:

    redis_cluster.set(key, value, ex=LOCK_EXPIRE, nx=True),这个set()方法共有四个参数:

    第一个为key,我们使用key来当锁,因为key是唯一的。

    第二个为value,传入value的原因就是上面所说的可靠性第四个条件解铃还须系铃人,通过传入value,我们就知道这把锁是哪个请求加的了,value可以通过uuid.uuid1().hex方法生成,uuid表示全局唯一标识符,不知道的同学自行百度。

    第三个为ex,意思是我们要给这个key设置一个过期时间。

    第四个为默认参数nx=True,意思SET IF NOT EXIST,就是当key不存在时才进行set操作,若key已经存在,则不做任何操作。

    总的来说,执行上面的set()方法会有两种结果:

    1.当前没有锁(key不存在),则进行加锁操作,并对锁设置过期时间,value表示拿到锁的线程。

    2.当前已经有锁(key已经存在),不做任何操作。

    我们的加锁代码满足前面说的可靠性里描述的三个条件。

    首先,set()加入了nx=True参数,,可以保证如果key已经存在,则函数不会调用成功,也就是只有一个线程能拿到锁,满足互斥性。

    其次,由于我们对锁设置了过期时间,即使锁的持有者后续发生崩溃而没有解锁,锁也会因为到了过期时间而自动解锁(即删除key),不会发生死锁。

    最后,因为我们传入value,并且uuid.uuid1()方法生成的value是唯一的,代表当前前加锁的线程,那么在解锁的时候就可以判断出是否为同一线程。

    解锁代码

    相关文章

      网友评论

          本文标题:python实现基于redis的分布式锁

          本文链接:https://www.haomeiwen.com/subject/ypmowqtx.html