美文网首页
Redis--实现分布式锁

Redis--实现分布式锁

作者: 凉初透的风 | 来源:发表于2019-08-23 17:08 被阅读0次

Redis分布式锁实现的方式:setnx
查看redis库的源码:

    def setnx(self, name, value):
        "Set the value of key ``name`` to ``value`` if key doesn't exist"
        return self.execute_command('SETNX', name, value)

setnx方法只有在key不存在时才能设置成功,否则设置失败。
设置成功时返回True,设置失败时返回False
具体思路:

首先定义一个RedisLock类,实现加锁功能。
__init__方法初始化redis的connect、是否加锁的Flag以及锁名。
get_lock方法目的是获取锁资源,主要思想是通过redissetnx方法的返回值来判断,当返回True时,表示加锁成功,当返回False时,表示加锁失败。锁名作为key,过期时间作为value。如果获取的value小于当前时间,则表示该lock已过期,同样可以获得锁资源。
release方法目的是释放锁资源。
最后定义一个有参装饰器,给需要加锁的方法或函数加锁。

Demo代码:

import time
import redis


class RedisLock(object):
    def __init__(self, key):
        # redis的连接,官方推荐ssshi用StrictRedis,而不是Redis
        self.rdcon = redis.StrictRedis(host='127.0.0.1', port=6379, password="", db=1, decode_responses=True)
        print(id(self.rdcon))
        # False代表未加锁,True代表加锁了
        self._lock = False
        # lock名字
        self.lock_key = "%s_dynamic_test" % key

    @staticmethod
    def get_lock(cls, timeout=10):
        while not cls._lock:
            print('try to get lock')
            # 过期时间,将作为lock_key的value
            timestamp = time.time() + timeout + 1
            # 设置lock_key,value为过期时间
            # 注:加锁成功返回Ture,加锁失败返回False
            cls._lock = cls.rdcon.setnx(cls.lock_key, timestamp)

            # 注意下方括号的范围,如果当前时间大于lock_key的value,那么也就是lock_key过期了
            if cls._lock or (time.time() > float(cls.rdcon.get(cls.lock_key)) and
                             time.time() > float(cls.rdcon.getset(cls.lock_key, timestamp))):

                print("get lock")
                break
            else:
                time.sleep(1)

    @staticmethod
    def release(cls):
        # 释放锁资源,即使lock_key未过期,也要释放锁资源
        if time.time() < float(cls.rdcon.get(cls.lock_key)):
            print("release lock")
            cls.rdcon.delete(cls.lock_key)


# 装饰器,用来加锁的装饰器
def deco(cls):
    def _deco(func):
        def __deco(*args, **kwargs):
            # 查看对象及地址
            print("before %s called [%s]." % (func.__name__, cls))
            # 装饰器传入的参数为redis的lock对象,调用get_lock方法,同时把自己当作参数传入
            cls.get_lock(cls)
            try:
                return func(*args, **kwargs)
            finally:
                cls.release(cls)

        return __deco

    return _deco


@deco(RedisLock("lock_key"))
def myfunc():
    print("myfunc() called.")
    time.sleep(5)


if __name__ == "__main__":
    myfunc()

相关文章

  • Redis--实现分布式锁

    Redis分布式锁实现的方式:setnx。查看redis库的源码: setnx方法只有在key不存在时才能设置成功...

  • 大佬浅谈分布式锁

    redis 实现 redis 分布锁一、redis 实现分布式锁(可重入锁)redission 实现分布式锁1、对...

  • 分布式锁实现

    基于数据库实现分布式锁基于缓存(redis,memcached)实现分布式锁基于Zookeeper实现分布式锁 s...

  • 基于redis的分布式锁

    分布式锁实现方案 基于数据库实现分布式锁 基于缓存(redis,memcached,tair)实现分布式锁 基于Z...

  • Zookeeper实现分布式锁(一)While版

    前面文章讲解了用Redis实现分布式锁的方式: 分布式锁之Redis实现(acquire)分布式锁之Redis实现...

  • 基于redis实现的分布式锁

    本文要点 基于redis实现分布式锁demo 基于redis实现分布式锁原理 基于redis实现分布式锁优缺点 正...

  • Redis--分布式锁

    2018-10-23 常用的四种方案:1 、基于数据库表做乐观锁,用于分布式锁增加版本号缺点:增加了一次selec...

  • Redis 如何实现分布式锁?ZooKeeper 如何实现分布式

    Redis 如何实现分布式锁?ZooKeeper 如何实现分布式锁?比较二者优劣? 分布式锁的三种实现: 基于数据...

  • 分布式 | 分布式锁的实现

    分布式锁的实现 在常见的分布式锁中有以下三种实现: Redis 实现 Zookeeper 实现 数据库实现 分布式...

  • Redis分布式锁实现方案

    1 Redis分布式锁的特性 在实现分布式锁时,需要保证锁实现的安全性和可靠性。基于这点特点,实现分布式锁需要具备...

网友评论

      本文标题:Redis--实现分布式锁

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