请帮我写一份redis分布式锁通用的lua脚本
时间: 2024-09-26 19:17:39 浏览: 48
redis实现分布式锁,自旋式加锁,lua原子性解锁
5星 · 资源好评率100%
Redis分布式锁是一种常见的解决高并发场景下资源互斥访问的技术。下面是一个简单的Lua脚本示例,用于获取和释放分布式锁。假设我们有一个名为`distributed_lock_key`的键作为锁标识符,`lock_timeout`是锁的有效期(单位秒),这里以秒为单位:
```lua
local lock_key = KEYS[1]
local lock_timeout = tonumber(ARGV[1])
local current_time = tonumber(redis.call("time"))
-- 获取锁
local result, unlock_script = redis.call(
"EVAL",
[[
if redis.call("EXISTS", KEYS[1]) == 0 then
-- 如果锁不存在,设置过期时间为锁超时时间
redis.call("PEXPIRE", KEYS[1], ARGV[1])
return true
end
-- 检查锁是否已过期,如果过期则尝试获取
local expired = redis.call("TTL", KEYS[1]) < 0
if expired or redis.call("GET", KEYS[1]) == ARGV[2] then
-- 如果锁已过期或当前持有者就是我们自己,则获取锁
redis.call("SET", KEYS[1], ARGV[2], "NX", "PX", ARGV[1])
return true
end
false
]],
2, -- 两个参数(锁标识和过期时间)
lock_key, -- 锁标识
lock_timeout -- 过期时间
)
if result then
-- 获取锁成功,返回true并保存解锁脚本
local script_id = result
else
-- 获取锁失败,解锁操作由其他客户端执行(如果之前保存了unlock_script)
if unlock_script then
redis.call("SCRIPT", "EXEC", unpack(unlock_script)) -- 执行解锁脚本
end
end
return result
```
这个脚本的工作流程大致如下:
1. 检查锁是否存在并检查其状态。
2. 如果锁不存在或过期,尝试设置一个新的锁,并且只允许设置一次(NX)并在指定时间内过期(PX)。
3. 如果获取锁成功,返回true;否则,返回false,并可能保存一个解锁脚本以便后续需要释放锁。
阅读全文