Redis可以用于实现分布式锁,主要利用两个方法:
一、SETNX + EX 方法
SETNX(SET if Not eXists) 如果一个键不存在的话就将此键设置为指定值,并返回1。
EX 为键设置一个过期时间。
具体实现方式:
SETNX lockKey someValue # 如果lockKey不存在就设置成功
EX lockKey 30 # 设置30秒过期时间
步骤:
- 使用SETNX尝试获取锁
- 如果获取成功,则执行任务代码
- 执行完成后删除锁
- 如果获取失败,则查询EX时间,在时间内循环重试
二、WATCH + MULTI + EXEC方法
使用Redis事务来尝试获取锁。
具体实现方式:
WATCH lockKey
# 判断是否存在,不存在则获取锁
if redis.get(lockKey) == null:
redis.multi()
redis.set(lockKey, 'value')
redis.exec()
# 执行任务代码
# 释放锁
redis.delete(lockKey)
redis.unwatch()
步骤:
- 使用WATCH监视锁 key
- 事务中尝试获取锁,如果成功则执行任务代码
- 释放锁,停止监视
这两种方式的区别是:
- SETNX + EX 效率较高,但存在失效问题
- WATCH + MULTI 机制安全,但效率较低
综上,Redis可以实现分布式锁的基本需求:
- 避免竞争获取锁(SETNX、WATCH)
- 避免死锁(锁过期、主动释放)
- 高可用(哨兵、集群模式)