版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/xiao_xia_ming/article/details/100564708
import time
import redis
class RedisLock(object):
def __init__(self, key):
self.rdcon = redis.Redis(host='127.0.0.1', port=6379, password="", db=1)
self._lock = 0
self.lock_key = "%s_dynamic_test" % key
@staticmethod
def get_lock(cls, timeout=10):
while cls._lock != 1:
timestamp = time.time() + timeout + 1
# 127.0.0.1:6379> SETNX 0 1567676678.05
# (integer) 1
# 127.0.0.1:6379> GET 0
# 1567676678.05
# 127.0.0.1:6379> GETSET 0 1567676678.05
# 1567676678.05
print cls._lock
print timestamp
# 商品秒杀
cls._lock = cls.rdcon.setnx(cls.lock_key, timestamp)
if cls._lock == 1 or (time.time() > cls.rdcon.get(cls.lock_key) and time.time() > cls.rdcon.getset(cls.lock_key, timestamp)):
print "get lock"
break
else:
time.sleep(0.3)
@staticmethod
def release(cls):
if time.time() < 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)
cls.get_lock(cls)
try:
return func(*args, **kwargs)
finally:
cls.release(cls)
return __deco
return _deco
@deco(RedisLock("6666"))
def myfunc():
print "myfunc() called."
time.sleep(20)
if __name__ == "__main__":
myfunc()
# 在传统的基于数据库的架构中,对于数据的抢占问题往往是通过数据库事务(ACID)来保证的。
# 在分布式环境中,出于对性能以及一致性敏感度的要求,使得分布式锁成为了一种比较常见而高效的解决方案。
# 使用场景:
# 某服务提供一组任务,A请求随机从任务组中获取一个任务;B请求随机从任务组中获取一个任务。
# 在理想的情况下,A从任务组中挑选一个任务,任务组删除该任务,B从剩下的的任务中再挑一个,任务组删除该任务。
# 同样的,在真实情况下,如果不做任何处理,可能会出现A和B挑中了同一个任务的情况。
# 分布式锁设计目标
# 可以保证在分布式部署的应用集群中,同一个方法在同一操作只能被一台机器上的一个线程执行。
# 这把锁要是一把可重入锁(避免死锁)
# 这把锁最好是一把阻塞锁(根据业务需求考虑要不要这条)
# 这把锁有高可用的获取锁和释放锁功能
# 这把锁获取锁和释放锁的性能要好……
# 商品提前设置到数据库里面,当在分布式的场景下面,顾客抢占到商品后就可以进行相应的删除
# 基于性能方面的考虑,redis相比mysql更有优势(对redis实现集群配置,或者RDB,AOF备份等)
————————————————
版权声明:本文为CSDN博主「xiao_xia_ming」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/xiao_xia_ming/article/details/100564708
python实现redis分布式锁
最新推荐文章于 2024-07-18 10:31:56 发布