Redis INCR Rate Limiter 2的竞争条件是什么?

时间:2018-03-13 07:31:31

标签: redis rate-limiting

我已阅读INCR文档here,但我无法理解为什么速率限制器2有竞争条件。

此外,文档中的the key will be leaked until we'll see the same IP address again是什么意思?

有人可以帮忙解释一下吗?非常感谢你!

1 个答案:

答案 0 :(得分:3)

您正在谈论以下代码,它在多线程环境中存在两个问题。

1. FUNCTION LIMIT_API_CALL(ip):
2. current = GET(ip)
3. IF current != NULL AND current > 10 THEN
4.     ERROR "too many requests per second"
5. ELSE
6.     value = INCR(ip)
7.     IF value == 1 THEN
8.         EXPIRE(ip,1)
9.     END
10.    PERFORM_API_CALL()
11.END
  

密钥将被泄露,直到我们再次看到相同的IP地址

如果客户端死亡,例如在执行LINE 8之前,客户端被终止或机器已关闭。然后,密钥ip将不会设置到期。如果我们再也看不到这个ip,那么这个密钥将永远存在于Redis数据库中,并且会被泄露。

  

速率限制器2具有竞争条件

假设数据库中不存在密钥ip。如果有10个客户端,例如20个客户端,请同时执行LINE 2。所有这些都将获得NULL current,它们都会进入ELSE子句。最后,所有这些客户端都将执行LINE 10,并且API将被调用超过10次。

此解决方案失败,因为这是LINE 2LINE 3之间的时间窗口。

正确的解决方案

value = INCR(ip)
IF value == 1 THEN
    EXPIRE(ip, 1)
END
IF value <= 10 THEN
    return true
ELSE
    return false
END

将上述代码包装到Lua脚本中,以确保它以原子方式运行。如果此脚本返回true,请执行API调用。否则,什么也不做。