Redis Lua脚本CAS操作失效:执行后foo值仍保持为1
问题根源分析
- Redis返回值类型不匹配:Redis的
GET命令返回的是字符串类型,在Lua中字符串"1"和数字1属于不同类型,直接用==比较会返回false,所以你脚本里的第一个判断if current == 1永远不会触发。 - 脚本执行失败的潜在原因:你提到尝试过
current = redis.call('GET','foo').ok,这个写法是错误的——redis.call('GET')返回的是字符串而非table结构,访问.ok会直接导致脚本执行报错,Redis会自动回滚脚本中的所有操作,因此foo的值不会发生任何改变。
解决方案
步骤1:修正脚本语法
使用正确的方式获取current值,只保留有效的字符串比较判断(数字比较可以直接删除,因为永远不会生效):
local current = redis.call('GET', 'foo') if current == '1' then redis.call('SET', 'foo', 3) end
步骤2:验证脚本执行结果
可以修改脚本让它返回执行前的current值,方便你确认脚本执行时的实际取值:
local current = redis.call('GET', 'foo') if current == '1' then redis.call('SET', 'foo', 3) end return current -- 返回执行前的foo值,用于验证
执行脚本命令:
redis-cli.exe --eval test.lua
如果返回"1",说明脚本执行时foo确实是"1",此时再执行GET foo应该返回3。
步骤3:排查脚本未生效的情况
如果执行后foo还是1,请检查以下内容:
- 执行脚本时是否指定了正确的Redis连接参数(比如密码、主机地址、端口),示例:
redis-cli.exe -h 127.0.0.1 -p 6379 -a yourpassword --eval test.lua - 查看Redis日志(日志路径可在Redis配置文件的
logfile字段中找到),确认脚本是否存在执行错误。
额外提示
在Lua脚本中操作Redis时,所有从Redis获取的值都是字符串类型,判断相等时一定要注意类型匹配。如果需要对值进行数值运算,记得用tonumber()做类型转换:
local current_num = tonumber(redis.call('GET', 'foo')) if current_num == 1 then redis.call('SET', 'foo', 2) end
内容的提问来源于stack exchange,提问作者Tiina
相关产品推荐
相关产品推荐

