redis分布式锁实现

setnx+setex:存在设置超时时间失败的情况,导致死锁

set(key,value,nx,px):将setnx+setex变成原子操作

问题:

  • 任务超时,锁自动释放,导致并发问题。使用redisson解决(看门狗监听,自动续期)

  • 加锁和释放锁不是同一个线程。在value中存入uuid(唯一标识),删除锁时判断该标识(使用lua脚本保证原子操作)

  • 不可重入,使用redisson解决(实现机制类似AQS,计数)

  • 异步复制可能造成锁丢失,使用redLock解决

lua脚本的示例
--[[
  传入参数:
  业务标识
  ip
  限制时间
  限制时间内的访问次数
]]--
local busIdentify   = tostring(KEYS[1])
local ip            = tostring(KEYS[2])
local expireSeconds = tonumber(ARGV[1])
local limitTimes    = tonumber(ARGV[2])

local identify  = busIdentify .. "_" .. ip

local times = redis.call("GET", identify)

--[[
  获取已经记录的时间
  获取到继续判断是否超过限制
  超过限制返回0
  否则加1,返回1
]]--
if times ~= false then
  times = tonumber(times)
  if times >= limitTimes then
    return 0
  else
    redis.call("INCR", identify)
    return 1
  end
end

-- 不存在的话,设置为1并设置过期时间
local flag = redis.call("SETEX", identify, expireSeconds, 1)

return 1

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值