【问题标题】:lua setting an expiration time using the redis command with 'setex' appears as a permanent key in openrestylua 使用带有“setex”的 redis 命令设置过期时间在 openresty 中显示为永久键
【发布时间】:2021-03-03 12:00:55
【问题描述】:

当我使用 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+

【问题讨论】:

    标签: redis lua openresty


    【解决方案1】:

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

    您的代码可能会发生这种情况:

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

    所以此时您拥有永久密钥。如果您想避免使用永久密钥,请使用类似:red:setex(key,2,tonumber(res)+1) 而不是 red:incr(key)

    【讨论】:

      猜你喜欢
      • 2020-03-22
      • 2019-06-18
      • 2018-09-09
      • 1970-01-01
      • 1970-01-01
      • 2020-02-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多