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 2
和 LINE 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 调用。否则什么都不做。
我已阅读 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 2
和 LINE 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 调用。否则什么都不做。