概述
分布式锁有几种实现方式, 若是用数据库实现, 可能会有性能的缺陷, 那么今天就来聊一聊缓存(Redis)来实现分布式锁;
实现
使用Redis实现分布式锁最简单的方案是使用命令SETNX。SETNX(SET if Not eXist)的使用方式为:SETNX key value,只在键key不存在的情况下,将键key的值设置为value,若键key存在,则SETNX不做任何动作。SETNX在设置成功时返回,设置失败时返回0。当要获取锁时,直接使用SETNX获取锁,当要释放锁时,使用DEL命令删除掉对应的键key即可。
这个方式跟之前用数据库的基于表记录实现差不多, 只不过换用了更高性能的缓存redis罢了, 所以他同样有一个缺点,就是如果因为某些错误, 而没有删除键key的时候, 会导致锁释放不掉, 不过这个问题比数据库的更好解决, 可以为这个key设置超时时间(这个一般redis key都是要的);
set命令用下面方式修饰:1
2
3
4* EX seconds:将键的过期时间设置为 seconds 秒。执行 SET key value EX seconds 的效果等同于执行 SETEX key seconds value 。
* PX milliseconds:将键的过期时间设置为 milliseconds 毫秒。执行 SET key value PX milliseconds 的效果等同于执行 PSETEX key milliseconds value 。
* NX:只在键不存在时,才对键进行设置操作。执行 SET key value NX 的效果等同于执行 SETNX key value.
* XX:只在键已经存在时,才对键进行设置操作。
创建一个锁, 设置过期为10s:
1 | SET lockKey lockValue EX 10 NX |
注意EX和PX不能同时使用,否则会报错:ERR syntax error。
解锁的时候还是使用DEL命令来解锁。
目前看上去方案就很完美, 但实际还是有隐患, 不完美;