• Redis分布式锁的实现(纯文字)


    在使用Redis的分布式集群的时候,我们进行操作的时候需要对抢锁,也就是对线程的操作权限

    我们在Redis中可以使用SetNX命令来进行锁争抢。

    sexnx(Key,value),其中的key指的是锁的唯一标识,value姑且为1。

    当锁抢成功,返回1则代表锁争抢成功。当然,我们接下来需要给锁一个有效时间,否则如果宕机的时候,进程挂掉,这个锁就一直不被释放,导致资源被占用。

    所以我们可以设置过期时间expire(30).

    有一个问题,因为争抢锁和设置过期时间的操作是分开的,所以在极端情况下,可能会出现抢到了锁,但是没有设置过期时间(在抢锁和设置过期时间之间服务器宕机)。也会发生资源一直被占用。

    所以我们需要确保我们的抢锁和设置过期时间的操作是原子性的(其实就是transaction)。

    所幸,我们可以使用set(key,value,expire,NX)来进行锁争抢。

    锁的争抢完成了。那么我们在写代码的时候,有必要使用代码在任务完成之后删除当前锁。这就可能出现锁误删。

    所以我们需要做判断,判断当前锁是否就是自己的那个线程中的锁。(保存线程ID可以使用抢锁时候的value)。

    就是当线程A抢锁之后设置了30S的过期时间,但是他的任务用时可能45S,在30S的时候,锁过期了。线程B抢到了锁,在B执行的过程中,A任务执行完了,他就会删除锁,此时就会把B的锁删掉。这是不可以的。

    但是这个不是原子性的。此时需要保证删除锁的操作也是原子性。

    但是无论在什么情况下情况下,同一时间有多个线程在访问同样的代码块,这是我们不允许的。所以我们需要保证这个锁,要在任务时间内,不能被释放掉。所以我们需要开启一个守护线程。

    开启一个守护线程,在我们的锁快要过期的时候,我们需要对锁进行续期,比如当剩下了1S的时候,我们可以再次设置过期时间为10S,一直循环往复。直到代码自己删除锁。

    守护线程的实现是-->争抢到所以后,开启一个本地队列Task,去轮询这个Key(间隔N秒去检查这个Key的过期时间,然后根据需要去对锁进行续时),直到代码释放锁。

  • 相关阅读:
    分享:十Python之Http Web服务(网页抓取二)
    分享:C语言打印long long类型
    分享:svn 添加*.so等文件
    visual assist x 安装
    设计模式之MVC模式
    php一个递归读取目录文件脚本
    转:javax.swing.JFrame中使用jpanel来布局
    alter table 总结
    php 函数:func_get_args()、func_get_arg()与func_num_args()
    Visual Assist X简介
  • 原文地址:https://www.cnblogs.com/zhangrgLearning/p/13256313.html
Copyright © 2020-2023  润新知