Redis实现分布式锁的方法

2025-01-15 02:38:25   小编

Redis实现分布式锁的方法

在分布式系统中,分布式锁是控制共享资源访问的关键技术,而Redis以其高性能和丰富的数据结构成为实现分布式锁的理想选择。以下将详细介绍Redis实现分布式锁的方法。

利用SETNX(SET if Not eXists)命令可以创建分布式锁。SETNX key value 命令,当且仅当键 key 不存在时,将键 key 的值设置为 value ,如果键 key 已经存在,则 SETNX 命令不做任何动作。示例代码如下:

import redis

r = redis.Redis(host='localhost', port=6379, db=0)
lock_key = 'distributed_lock'
lock_value = 'unique_value'

if r.setnx(lock_key, lock_value):
    try:
        # 获得锁后执行的业务逻辑
        print("获得锁,执行操作")
    finally:
        r.delete(lock_key)  # 释放锁
else:
    print("未能获得锁")

虽然SETNX能实现基本的锁功能,但存在一些问题,比如锁没有过期时间,若持有锁的进程崩溃,锁将永远无法释放。为解决此问题,在设置锁时需添加过期时间。在Redis 2.6.12版本之后,可以使用 SET key value [EX seconds] [PX milliseconds] [NX|XX] 命令,它是一个原子操作,既设置了锁的值又设置了过期时间。代码示例:

if r.set(lock_key, lock_value, ex=10, nx=True):
    try:
        print("获得锁,执行操作")
    finally:
        r.delete(lock_key)
else:
    print("未能获得锁")

不过,释放锁时可能会出现误删情况。比如,线程A获取了锁并设置了过期时间,在业务逻辑执行过程中,由于某些原因锁过期了,此时线程B获取到锁。随后线程A执行完业务逻辑准备释放锁,却会把线程B的锁误删。可以通过给锁设置唯一标识来解决,只有锁的持有者才能删除锁。示例如下:

lock_value = str(uuid.uuid4())
if r.set(lock_key, lock_value, ex=10, nx=True):
    try:
        print("获得锁,执行操作")
    finally:
        script = """
        if redis.call("GET", KEYS[1]) == ARGV[1] then
            return redis.call("DEL", KEYS[1])
        else
            return 0
        end
        """
        r.eval(script, 1, lock_key, lock_value)
else:
    print("未能获得锁")

通过以上方法,能在Redis中实现较为安全、可靠的分布式锁,有效控制分布式系统中共享资源的访问,确保系统的稳定性和数据的一致性。

TAGS: Redis 分布式锁 Redis分布式锁 锁实现

欢迎使用万千站长工具!

Welcome to www.zzTool.com