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

What is the race condition for Redis INCR Rate Limiter 2?

我已阅读 INCR 文档 here,但我不明白为什么 Rate limiter 2 有竞争条件。

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

谁能帮忙解释一下?非常感谢!

你说的是下面的代码,在multiple-threaded环境下有两个问题。

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

the key will be leaked until we'll see the same IP address again

如果客户死亡,例如在执行 LINE 8 之前,客户端被杀死或机器停机。那么密钥 ip 将不会被设置过期。如果我们再也见不到这个 ip,这个密钥将永远保存在 Redis 数据库中,并被泄露。

Rate limiter 2 has a race condition

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

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

一个正确的解决方案

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

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