Redis 分布式锁
redis 实现分布式锁
1.setnx
使用setnx 命令创建一个值.创建之后不可以被更改,因为一直被占用
使用expire设置设置生存时间,过期之后就会自动删除
127.0.0.1:6379> setnx locknx test
(integer) 1
127.0.0.1:6379> setnx locknx t
(integer) 0
127.0.0.1:6379> get locknx
"test"
127.0.0.1:6379> expire locknx 2
(integer) 1
127.0.0.1:6379> setnx locknx t
(integer) 1
127.0.0.1:6379> get locknx
"t"
用java实现
Jedis jedis = new Jedis("127.0.0.1", 6379);
long status = jedis.setnx("locknx","test");
//成功
if (status==1){
jedis.expire("locknx",10);
//执行独占资源操作
}
但是这种方式还是有问题如果执行到第一步时就报错了,没有释放资源,那么这个锁就会一直被占用
2.SET key value [EX seconds] [PX milliseconds] [NX|XX]
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 : 只在键已经存在时, 才对键进行设置操作。
127.0.0.1:6379> set locknx test ex 10 nx
OK
127.0.0.1:6379> set locknx test ex 10 nx
(nil)
127.0.0.1:6379>
第一次执行返回ok,然就在10秒内再执行就返回nil.
java代码
Jedis jedis = new Jedis("127.0.0.1", 6379);
String result = jedis.set("locknx","test","nx","ex",10);
//成功
if (result.equals("ok")){
//执行独占资源操作
}
大量key同时过期的注意事项
集中过期,由于清除大量的key很耗时,会出现短暂卡顿.
解决办法:在设置key过期时,给每个key加上随机值.