美文网首页redis
redis分布式锁--001(组合命令的演变过程)

redis分布式锁--001(组合命令的演变过程)

作者: 天的安排 | 来源:发表于2019-08-12 19:33 被阅读0次

    分布式锁

    分布式锁本质上要实现的目标就是在 Redis 里面占一个“茅坑”,当别的进程也要来占
    

    时,发现已经有人蹲在那里了,就只好放弃或者稍后再试。
    占坑一般是使用 setnx(set if not exists) 指令,只允许被一个客户端占坑。先来先占, 用
    完了,再调用 del 指令释放茅坑。



    但是有个问题,如果逻辑执行到中间出现异常了,可能会导致 del 指令没有被调用,这样
    就会陷入死锁,锁永远得不到释放。
    于是我们在拿到锁之后,再给锁加上一个过期时间,比如 5s,这样即使中间出现异常也
    可以保证 5 秒之后锁会自动释放。



    但是以上逻辑还有问题。如果在 setnx 和 expire 之间服务器进程突然挂掉了,可能是因
    为机器掉电或者是被人为杀掉的,就会导致 expire 得不到执行,也会造成死锁。
    这种问题的根源就在于 setnx 和 expire 是两条指令而不是原子指令。如果这两条指令可
    以一起执行就不会出现问题。也许你会想到用 Redis 事务来解决。但是这里不行,因为 expire

    是依赖于 setnx 的执行结果的,如果 setnx 没抢到锁,expire 是不应该执行的。事务里没有 if-
    else 分支逻辑,事务的特点是一口气执行,要么全部执行要么一个都不执行。
    为了解决这个疑难,Redis 开源社区涌现了一堆分布式锁的 library,专门用来解决这个问
    题。实现方法极为复杂,小白用户一般要费很大的精力才可以搞懂。如果你需要使用分布式锁,意味着你不能仅仅使用 Jedis 或者 redis-py 就行了,还得引入分布式锁的 library。



    为了治理这个乱象,Redis 2.8 版本中作者加入了 set 指令的扩展参数,使得 setnx 和
    expire 指令可以一起执行,彻底解决了分布式锁的乱象。从此以后所有的第三方分布式锁
    library 可以休息了。 > set lock:codehole true ex 5 nx OK ... do something critical ... > del
    lock:codehole 上面这个指令就是 setnx 和 expire 组合在一起的原子指令,它就是分布式锁的
    奥义所在

    相关文章

      网友评论

        本文标题:redis分布式锁--001(组合命令的演变过程)

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