前言
Redis是一个使用ANSI C编写的开源、支持网络、基于内存、可选持久性的键值对存储数据库。同时也是最流行的键值对存储数据库(之一)。
由于其基于内存的特性,在使用上轻量高速,在面对并发场景时,可以基于其构建并发锁(分布式锁)。
分布式锁一般有三种实现方式:
- 数据库锁
- 基于Redis的分布式锁
- 基于ZooKeeper的分布式锁
实现
import redis
def get_redis_client(host, port, db):
redis_client = redis.Redis(
host=host, port=port, db=db, decode_responses=True)
return redis_client
# 获取锁,锁过期时间默认30s
def acquire_lock(lock_key, time_out=30):
# 生成唯一id
identifier = str(lock_key)
lock_key = "lock_key:" + lock_key
with get_redis_client() as redis_client:
# setnx & expire, 只有key不存在情况下,将key的值设置为value,若key存在则不做任何动作。
if redis_client.set(lock_key, identifier, nx=True, ex=time_out):
return identifier
return False
# 锁的释放
def release_lock(lock_key, identifier):
lock_key = "lock_key:" + lock_key
with get_redis_client() as redis_client:
try:
if redis_client.get(lock_key) == identifier: # 检查客户端是否仍然持有该锁
# 删除键,释放锁
redis_client.delete(lock_key)
return True
except redis.exceptions.WatchError:
# 锁释放失败
print(f"release_lock {lock_key} has exceptions.")
return False
if __name__ == "__main__":
wait_flag = True
lock_key = 'test_key'
while wait_flag:
identifier = acquire_lock(lock_key) # 获取锁
if identifier:
try:
pass #正常处理
except Exception:
pass #异常处理
finally:
wait_flag = False
release_flag = release_lock(lock_key, identifier) # 释放锁
参考资料
[1] Mac快速安装使用Redis
[2] Docs » Redis 命令参考
[3] python基于redis实现分布式锁
[4] redis操作五种数据的命令说明
[5] Redis:解决分布式高并发修改同一个Key的问题
[6] Python实现了一个基于redis的分布式可重入锁,Redis
[7] 分布式锁解决并发的三种实现方式