一架梯子,一头程序猿,仰望星空!
Redis面试题 > 内容正文

Redis如何实现分布式锁?


问题简答

Redis实现分布式锁,主要通过使用SETNX命令结合过期时间实现,即在Redis中创建一个唯一的锁标识符,当SETNX返回1时,表示获取到锁,设置过期时间避免死锁;当SETNX返回0时,表示锁已经被占用,需要等待重试。

问题详解:

Redis实现加锁过程

  1. 通过SET key value NX PX milliseconds命令向Redis中添加一个带有指定超时时间的key-value键值对,如果key不存在则添加成功,表示获取到了锁,否则添加失败,表示锁已被其他客户端获取。
  2. 使用DEL key命令删除key值,释放锁。

例子:

# 尝试加锁,若 key 不存在则添加 key,设置值为 1,并且设置过期时间为 10 秒
# 注意,加锁的 key 应该是全局唯一的,一般可以使用业务名称 + 锁名称的方式命名
# NX 代表,key不存在才能set成功
SET lock_key 1 NX EX 10

# 返回值为 OK,则表示获取锁成功,可以执行加锁之后的业务逻辑
# 返回值为 nil,则表示获取锁失败,需要等待一段时间后重试,或者抛出加锁失败的异常

Redis加锁注意事项

  1. 锁竞争:当多个进程同时请求获取同一把锁时,可能会出现竞争,导致只有一个进程获取到锁,而其他进程需要等待,降低了系统的并发性能,所有锁都有这个问题,只能减少加锁,能不加锁就不加锁。
  2. 锁过期:如果加锁后,没有及时释放锁,可能会出现死锁,导致系统资源无法释放,设置好锁的过期时间可以缓解这个问题。
  3. 误删锁:如果误删了一个已经被其他进程持有的锁,就会导致其他进程不能正确执行,产生数据异常等问题,建议在set设置锁的时候value保存当前进程或者线程的唯一标识,删除锁的时候检查下锁是不是自己的。
  4. 不可重入:Redis锁并不是可重入锁,如果在获取锁之后,再次请求获取锁,就会导致死锁。