基于 SETNX 的分布式锁实现
1. 获取锁:
def acquire_lock(redis_conn, lock_key, acquire_timeout=10, lock_timeout=10):
end_time = time.time() + acquire_timeout
while time.time() < end_time:
if redis_conn.setnx(lock_key, "locked"):
redis_conn.expire(lock_key, lock_timeout)
return True
time.sleep(0.001) # 避免过于频繁地尝试获取锁
return False
这段代码尝试使用 SETNX 命令在 Redis 中创建一个键(锁)。如果创建成功,表示获取到了锁,设置锁的过期时间,然后返回 True。如果在一定时间内未能获取锁,则返回 False。
2. 释放锁:
def release_lock(redis_conn, lock_key):
return redis_conn.delete(lock_key)
这段代码使用 DEL 命令删除锁,从而释放锁。
注意事项:
- 原子性: SETNX 操作是原子的,它要么成功,要么失败,不存在中间状态。这确保了在并发情况下只有一个客户端能够成功获取锁。
- 过期时间: 设置锁的过期时间是为了确保即使锁的持有者出现问题导致未能正常释放锁,锁也能在一定时间后自动过期,避免死锁。
- 释放锁的安全性: 释放锁的操作是通过 DEL 命令删除锁,确保只有持有锁的客户端才能释放它。
- 超时机制: 在获取锁的过程中,设置了一个获取超时时间,避免长时间等待。
这是一个基本的分布式锁实现方法,但在实际应用中,还需要考虑更多的因素,例如使用锁的业务场景、容错处理、重试机制等。此外,考虑使用 Redis 的 SET 命令的扩展参数,如 SET key value [EX seconds] [NX|XX],能够更加简洁地实现获取锁和设置过期时间。
转载请注明出处:http://www.zyzy.cn/article/detail/9094/Redis