1

setting an expiration time using the redis command appears as a permanent key when i do this in openresty with lua script. the lua script is follow this:

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

When the openresty program has run for some time,some permanent keys appear in redis.From this function it can be seen that I did not set a key for the permanent time,but it just happens. Why is that,please help me answer this question. Thank you!
The software version is as follows:

  • openresty: 1.17.8.2
  • redis: 6.0+
  • centos: 8.0+
Leandy
  • 595
  • 1
  • 5
  • 14

1 Answers1

1

Openresty connects to redis database and uses it's functionality. Such usage of redis functions in lua or other language is not atomic. For redis server it means: [redis:get, pause, redis:setex] or [redis:get, pause, redis:incr]. During pause period can happen a lot of things, event if there is only 1ms, such as cleanup of 'dead' keys.

And this what could happen with your code:

  • local resp, err = red:get(key)
  • You get valid key value which is smaller than limit_num
  • ok, err = red:incr(key)
  • Redis checks if key is valid, and removes it if reaches ttl
  • Redis checks that there is no such key, so creates key with value=0 and increments key value

So at this point you have permanent key. If you want to avoid permanent keys, use something like: red:setex(key,2,tonumber(res)+1) istead of red:incr(key)

Darius
  • 1,060
  • 2
  • 6
  • 17