gpt4 book ai didi

redis - 这个处理 key 过期竞争条件的redis lua脚本是纯函数吗?

转载 作者:IT王子 更新时间:2023-10-29 06:03:49 27 4
gpt4 key购买 nike

我一直在使用 redis 来跟踪分布式系统中外部 api 的速率限制。我决定为存在限制的每条路线创建一个 key 。 key 的值是在限制重置之前我仍然可以发出多少请求。并且通过将 key 的 TTL 设置为限制重置的时间来进行重置。

为此,我编写了以下 lua 脚本:

if redis.call("EXISTS", KEYS[1]) == 1 then
local remaining = redis.call("DECR", KEYS[1])
if remaining < 0 then
local pttl = redis.call("PTTL", KEYS[1])
if pttl > 0 then
--[[
-- We would exceed the limit if we were to do a call now, so let's send back that a limit exists (1)
-- Also let's send back how much we would have exceeded the ratelimit if we were to ignore it (ramaning)
-- and how long we need to wait in ms untill we can try again (pttl)
]]
return {1, remaining, pttl}
elseif pttl == -1 then
-- The key expired the instant after we checked that it existed, so delete it and say there is no ratelimit
redis.call("DEL", KEYS[1])
return {0}
elseif pttl == -2 then
-- The key expired the instant after we decreased it by one. So let's just send back that there is no limit
return {0}
end
else
-- Great we have a ratelimit, but we did not exceed it yet.
return {1, remaining}
end
else
return {0}
end

Since a watched key can expire in the middle of a multi transaction without aborting it .我假设 lua 脚本也是如此。因此,我将 ttl 为 -1 或 -2 的情况放入。

在我写完那个脚本后,我更深入地查看了 eval 命令页面,发现 lua 脚本必须是 pure function。 .

里面写着

The script must always evaluates the same Redis write commands with the same arguments given the same input data set. Operations performed by the script cannot depend on any hidden (non-explicit) information or state that may change as script execution proceeds or between different executions of the script, nor can it depend on any external input from I/O devices.

根据这个描述,我不确定我的函数是否是纯函数。

最佳答案

在 Itamar 的回答之后,我想亲自确认一下,所以我写了一个小的 lua 脚本来测试它。脚本创建一个具有 10 毫秒 TTL 的 key 并检查 ttl 直到它小于 0:

redis.call("SET", KEYS[1], "someVal","PX", 10)
local tmp = redis.call("PTTL", KEYS[1])
while tmp >= 0
do
tmp = redis.call("PTTL", KEYS[1])
redis.log(redis.LOG_WARNING, "PTTL:" .. tmp)
end
return 0

当我运行这个脚本时,它从未终止。它只是继续向我的日志发送垃圾邮件,直到我杀死了 redis 服务器。然而,当脚本运行时时间不会停止,而是在 TTL 为 0 时停止。

所以 key 会老化,它永远不会过期。

关于redis - 这个处理 key 过期竞争条件的redis lua脚本是纯函数吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49158805/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com