首页 > 数据库 >基于redis实现可重入分布式锁

基于redis实现可重入分布式锁

时间:2024-06-04 18:35:20浏览次数:26  
标签:重入 count -- redis value call local 分布式

前提

redis+lua

原理

采用redis hash数据类型,实现分布式可重入锁

hash结构中存储字段value,count

value:加锁的值,重入加锁时判断当前value和传入的value是否相等,相等情况下认为是重入锁,将count加一,不等属于其他场景抢占锁,该情况下获取锁失败

锁释放时,判断value是否相等,相等情况下是当前锁持有者释放锁场景,将count减一,count为0 时,锁释放完毕,将key删除

count:重入次数

 

注:加锁次数和释放锁次数必须一致

脚本

-- 可重入锁加锁
local lockInfo = redis.call('hmget',KEYS[1],'value','count')
local value = lockInfo[1]
local count = lockInfo[2]
local reqValue = ARGV[1]
local expireTime = ARGV[2]
-- 判断是否初次加锁
if value==false or count==false then
    -- 更新锁信息
    redis.call('hmset',KEYS[1],'value',reqValue,'count',1)
    redis.call('expire',KEYS[1],tonumber(expireTime))
    return 1
else
    -- 判断是否重入锁
    if reqValue == value then
        -- 重入锁更新次数
        count = count+1
        redis.call('hmset',KEYS[1],'count',count)
        redis.call('expire',KEYS[1],tonumber(expireTime))
        return 1
    end
    return 0
end

-- 可重入锁释放
local lockInfo = redis.call('hmget',KEYS[1],'value','count')
local value = lockInfo[1]
local count = lockInfo[2]
local reqValue = ARGV[1]
if value~=false and count~=false then
    -- 只能删除自己加锁的数据
    if value == reqValue then
        count = count-1
        if count>0 then
            -- 更新次数
            redis.call('hmset',KEYS[1],'count',count)
            return 1
        else
            -- 次数为0,此时直接删除
            redis.call('del',KEYS[1])
            return 1
        end
    else
        return 0
    end
else
    return 0
end

 

标签:重入,count,--,redis,value,call,local,分布式
From: https://www.cnblogs.com/tangs1/p/18231466

相关文章

  • redis限流
    前提redis+lua 滑动窗口--滑动窗口localkey=KEYS[1]localmaxSize=ARGV[1]localcurrentTime=ARGV[2]localstartTime=ARGV[3]localuuid=ARGV[4]localcurrentCount=redis.call('zcount',key,startTime,currentTime)if(currentCountandtonumber......
  • 12- Redis 中的 链表 数据结构
    Redis的List对象的底层实现之一就是链表。C语言本身没有链表这个数据结构,所以Redis自己设计了一个链表数据结构。1.链表节点结构设计先来看看【链表节点】结构的样子:typedefstructlistNode{  //前置节点  structlistNode*prev;  //后置节点 ......
  • CentOS-7.9 安装redis7.0.5步骤
     下载Redis7.0.5的源代码wgethttp://download.redis.io/releases/redis-7.0.5.tar.gz解压并进入源代码目录tarzxfredis-7.0.5.tar.gzcdredis-7.0.5编译和安装,并指定安装目录,并复制Redis配置文件makesudomakePREFIX=/usr/local/redisinstallcpredis.conf......
  • CSRedis用于Redis哨兵模式,NetCore
    十年河东,十年河西,莫欺少年穷学无止境,精益求精上一节通过两台windowsServer服务器部署了Redis的哨兵模式,详情参考:两台windowserver服务器配置Redis哨兵集群----一主二从redis通过主从复制来实现高可用,但是发生故障时需要人工进行主从切换,效率低下。哨兵机制实现了redis主从的自......
  • Conts7 安装Redis教程
    1.添加软件安装源yuminstalleple-release2.安装Redisyuminstallredis-y3.启动redissystemctlstartredis4.允许开机启动systemctlenableredis5.修改redis配置文件vim/ect/redis.conf修改2处文件(虚拟机)6.重启redissystemctlrestartredis7.登陆redis数......
  • redis - [03] 配置&命令
    题记部分 一、配置(Config)  二、命令(Command)(1)启动redis服务:redis-server.exeredis.windows.conf(2)连接redis-server:redis-cli-hhost-pport-apassword(3)查看key是否存在:existsmyKey(4)查看key的值:getmyKey(5)序列化给定key,返回序列化的值(不会改变key的值):dumpmy......
  • Redis之set
    SetRedis的Set是String类型的无序集合。集合成员是唯一的,这就意味着集合中不能出现重复的数据。(无序不重复)集合对象的编码可以是intset或者hashtable。Redis中集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是O(1)。案例127.0.0.1:6379>SADDmysethe......
  • Redis之list
    Redis列表(List)Redis列表是简单的字符串列表,按照插入顺序排序。你可以添加一个元素到列表的头部(左边)或者尾部(右边)一个列表最多可以包含2^32-1个元素(4294967295,每个列表超过40亿个元素)。list可以定义一些规则,使它作为栈、队列或双端队列。案例LPUSH&RPUSH127.......
  • 面试必会->Redis篇
    01-你们项目中哪里用到了Redis?在我们的项目中很多地方都用到了Redis,Redis在我们的项目中主要有三个作用:使用Redis做热点数据缓存/接口数据缓存使用Redis存储一些业务数据,例如:验证码,用户信息,用户行为数据,数据计算结果,排行榜数据等使用Redis实现分布......
  • [redis 源码走读] - 跳跃表(skiplist)
    作者简介:大家好,我是smart哥,前中兴通讯、美团架构师,现某互联网公司CTO联系qq:184480602,加我进群,大家一起学习,一起进步,一起对抗互联网寒冬学习必须往深处挖,挖的越深,基础越扎实!阶段1、深入多线程阶段2、深入多线程设计模式阶段3、深入juc源码解析阶段4、深入jdk其余源码解析......