如何通过 Redis 实现分布式锁

 

分布式锁需要解决的问题:

  • 互斥性:任意时刻只能有一个客户端获取锁
  • 安全性:锁只能被持有该锁的客户端删除 
  • 死锁:获取锁的客户端因为意外宕机未能释放锁,其他客户端再也无法获取到该锁导致死锁
  • 容错:宕机后客户端仍然可以获取、释放锁

 

SETNX key value:如果 key 不存在,即创建并赋值;

时间复杂度O(1);

返回值设置:设置成功返回1,设置失败返回0;

 

如何解决 SETNX 长期有效的问题?

EXPIRE key seconds

设置 key 的生存时间,当 key 过期时(生存时间为0),会被自动删除

 

RedisService redisService = SpringUtils.getBean(RedisService.class);

long status = redisService.setnx(key,"1");

if(status == 1){
    redisService.expire(key,expire);
    //执行独占资源逻辑
    do0cuppiedWork();
}

 

缺点:原子性得不到满足

 

SET key value [EX seconds] [PX milliseconds] [NX|XX]

-EX seconds:设置键的过期时间为 second 秒

-PX milliseconds:设置键的过期时间为 milliseconds 毫秒

-NX:只在键不存在时,才对键进行设置操作

-XX:只在键已经存在时,才对键进行设置操作

-SET操作完成时,返回OK,否则返回nil

 

大量的 key 同时过期的注意事项

-集中过期,由于清除大量的 key 很耗时,会出现短暂的卡顿现象

-解决方案:在设置 key 的过期时间的时候,给每个 key 加上随机值

 

posted @ 2019-04-30 15:41  Roni_i  阅读(163)  评论(0编辑  收藏  举报