美文网首页
如何通过Redis实现分布式锁

如何通过Redis实现分布式锁

作者: 叫我胖虎大人 | 来源:发表于2020-03-06 21:08 被阅读0次

    分布式锁需要解决的问题

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

    如何利用Redis实现分布式锁

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

    • 时间复杂度:O(1)
    • 返回值:设置成功,返回1;设置失败,返回0;

    客户端通过去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]

    • EX second :设置键的过期时间为second秒
    • PX millisecond :设置键的过期时间为millisecond毫秒
    • NX :只在键不存在时,才对键进行设置操作
    • XX :只在键已经存在时,才对键进行设置操作
    • SET操作成功完成时,返回OK ,否则返回nil

    代码实现

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

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

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

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

    相关文章

      网友评论

          本文标题:如何通过Redis实现分布式锁

          本文链接:https://www.haomeiwen.com/subject/orynrhtx.html