Redis Lua脚本编程指南
一 核心概念与优势
二 执行与管理脚本
| 命令 | 作用 | 示例 |
|---|---|---|
| EVAL | 直接执行脚本 | EVAL “return redis.call(‘GET’,KEYS[1])” 1 mykey |
| SCRIPT LOAD | 将脚本加载进缓存并返回SHA1 | SCRIPT LOAD “return ‘Hello’” |
| EVALSHA | 通过SHA1执行已缓存脚本 | EVALSHA |
| SCRIPT EXISTS | 检查脚本是否已缓存 | SCRIPT EXISTS |
| SCRIPT FLUSH | 清空脚本缓存(Redis 4.0+ 支持 ASYNC) | SCRIPT FLUSH [ASYNC] |
| SCRIPT KILL | 终止正在执行的脚本(仅当脚本未修改数据时可用) | SCRIPT KILL |
| SCRIPT DEBUG | 开启/关闭脚本调试模式(便于排查) | SCRIPT DEBUG on/off |
三 脚本编写规范与数据类型
| Redis 回复类型 | Lua 类型 |
|---|---|
| integer reply | number |
| bulk reply | string |
| multi bulk | table |
| status reply | table 且含字段 ok |
| error reply | table 且含字段 err |
| nil reply | false |
四 实战示例
-- KEYS[1]: 计数器键;ARGV[1]: 最大值
local cur = tonumber(redis.call('GET', KEYS[1]) or 0)
local max = tonumber(ARGV[1])
local nxt = cur + 1
if nxt > max then nxt = 0 end
redis.call('SET', KEYS[1], nxt)
return nxt
-- KEYS[1]: 锁键;ARGV[1]: 唯一标识(如UUID);ARGV[2]: 过期毫秒
local key, token, ttl = KEYS[1], ARGV[1], tonumber(ARGV[2])
local ok = redis.call('SET', key, token, 'NX', 'PX', ttl)
if ok then
return 1 -- 加锁成功
else
-- 仅当值匹配时续期,避免误续他人锁
local cur = redis.call('GET', key)
if cur == token then
redis.call('PEXPIRE', key, ttl)
return 1 -- 续期成功
end
return 0 -- 加锁失败
end
-- KEYS[1]: 计数器键;ARGV[1]: 阈值;ARGV[2]: 窗口秒数
local key, limit, window = KEYS[1], tonumber(ARGV[1]), tonumber(ARGV[2])
local cur = redis.call('INCR', key)
if cur == 1 then
redis.call('EXPIRE', key, window) -- 首次访问设置过期
end
if cur > limit then
return 0 -- 拒绝
else
return 1 -- 放行
end
-- KEYS[1]: 库存键;KEYS[2]: 已购集合(去重);ARGV[1]: 扣减数量;ARGV[2]: 用户ID
local stock = tonumber(redis.call('GET', KEYS[1]))
local deduct = tonumber(ARGV[1])
if not stock or stock < deduct then
return 0 -- 库存不足
end
redis.call('DECRBY', KEYS[1], deduct)
redis.call('SADD', KEYS[2], ARGV[2])
return 1 -- 扣减成功
五 最佳实践与常见坑
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。