如何通过Redis实现分布式锁

2020-03-06  本文已影响0人  叫我胖虎大人

分布式锁需要解决的问题

互斥性 任意时刻只能有一个客户端获取到锁
安全性 锁只能由拥有该锁的客户端删除
死锁 获取锁的客户端因为某些原因宕机而未能释放锁,而导致其他客户端再也无法获取到该锁
容错 部分节点宕机的时候Redis依然能够获取锁和释放锁

如何利用Redis实现分布式锁

在Redis中存在setnx key value的命令,如果key存在,则创建并赋值

客户端通过去setnx(具有原子性)一个key的返回值来判断能否获取到锁

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

为什么需要解决长期有效的问题,线程异常,未正确释放。

expire key seconds

代码实现

long status = redisService.setnx(key,"1");
if(status == 1) {
    redisService.expire(key,seconds);
    //执行独占资源逻辑
    doOccupiedWork();
}

存在的问题

setnxexpire两个原子性操作联合起来不在具有原子性,如果在第三行代码执行过程中发生了中断,

那么这个key将一直不会过期。

解决方案

在Redis2.6之后,将setnxexpire融合了起来,使其具有原子性,具体操作如下。

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

代码实现

String result = redisService.set(lockKey,requestId,SET_IF_NOT_EXISTS,SET_WITH_EXPIRE_TIME,expireTime);
if("OK".equals(result)) {
    //执行独占资源逻辑
    doOccupiedWork();
}

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

存在的问题:集中过期,由于清除大量的key很耗时,会出现短暂的卡顿现象。

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

上一篇下一篇

猜你喜欢

热点阅读