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)