Redis 在分布式锁方面的用法有哪些?

Redis可以用于实现分布式锁,主要利用两个方法:
一、SETNX + EX 方法
SETNX(SET if Not eXists) 如果一个键不存在的话就将此键设置为指定值,并返回1。
EX 为键设置一个过期时间。

具体实现方式:

SETNX lockKey someValue   # 如果lockKey不存在就设置成功  
EX lockKey 30    # 设置30秒过期时间

步骤:

  1. 使用SETNX尝试获取锁
  2. 如果获取成功,则执行任务代码
  3. 执行完成后删除锁
  4. 如果获取失败,则查询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()

步骤:

  1. 使用WATCH监视锁 key
  2. 事务中尝试获取锁,如果成功则执行任务代码
  3. 释放锁,停止监视

这两种方式的区别是:

  • SETNX + EX 效率较高,但存在失效问题
  • WATCH + MULTI 机制安全,但效率较低

综上,Redis可以实现分布式锁的基本需求:

  • 避免竞争获取锁(SETNX、WATCH)
  • 避免死锁(锁过期、主动释放)
  • 高可用(哨兵、集群模式)