Lua 使用带有"setex"的 redis 命令设置过期时间在 Openresty 中显示为永久密钥


使用lua脚本在openresty中设置过期时间时,使用redis命令设置过期时间将显示为一个永久键。lua脚本如下:
local function ip_frequency(ip,red)
local limit_num=50
local key = "limit:frequency:"..ip
local resp, err = red:get(key)
if resp==nil then   
local ok,err=red:setex(key,2,1)
if not ok then
return false;
end
end  
if type(resp) == "string" then 
if tonumber(resp) > limit_num then
return false
end
end
ok, err = red:incr(key)  
if not ok then
return false
end
return true
end

当openresty程序运行了一段时间后,一些永久键会出现在redis中。从这个函数可以看出,我没有为永久时间设置密钥,但它只是发生了。为什么,请帮我回答这个问题。谢谢
软件版本如下:

  • openresty:1.17.8.2
  • redis:6.0+
  • centos:8.0+

Openresty连接到redis数据库并使用它的功能。redis函数在lua或其他语言中的这种用法是而不是原子。对于redis服务器,它的意思是:[redis:get,暂停,redis:setex]或[redis:get,暂停,redis:incr]。在暂停期间可能会发生很多事情,如果只有1ms的事件,比如清除"死"键。

这就是你的代码可能发生的情况:

  • local resp, err = red:get(key)
  • 您得到的密钥值小于limit_num
  • ok, err = red:incr(key)
  • Redis检查密钥是否有效,如果达到ttl则将其删除
  • Redis检查是否没有这样的键,因此创建值为0的键并增加键值

所以在这一点上你有了永久密钥。如果您想避免使用永久密钥,请使用以下内容:red:setex(key,2,tonumber(res)+1)istead ofred:incr(key)

最新更新