Redis的三种限流方法以及代码详解
Redis 提供了几种不同的方法来实现限流,以下是三种常见的限流方法及其代码示例:
- 使用 Redis 的 INCR 和 EXPIRE 命令
import redis
def is_rate_limited(redis_conn, user_id, max_requests, duration):
key = f"user:{user_id}:rate_limit"
requests = redis_conn.incr(key)
if requests == 1:
redis_conn.expire(key, duration)
if requests > max_requests:
return True
else:
return False
r = redis.Redis(host='localhost', port=6379, db=0)
user_id = "user123"
max_requests = 10
duration = 60 # 60 seconds
if is_rate_limited(r, user_id, max_requests, duration):
print("User has exceeded the rate limit.")
else:
print("User is within the rate limit.")
- 使用 Redis 的 LUA 脚本
import redis
rate_limit_script = """
local key = KEYS[1]
local limit = tonumber(ARGV[1])
local current = redis.call('get', key)
if current and tonumber(current) > limit then
return true
else
if current then
redis.call('incr', key)
else
redis.call('set', key, 1)
redis.call('expire', key, ARGV[2])
end
return false
end
"""
def is_rate_limited(redis_conn, user_id, max_requests, duration):
key = f"user:{user_id}:rate_limit"
script = redis_conn.register_script(rate_limit_script)
return script(keys=[key], args=[max_requests, duration])
r = redis.Redis(host='localhost', port=6379, db=0)
user_id = "user123"
max_requests = 10
duration = 60 # 60 seconds
if is_rate_limited(r, user_id, max_requests, duration):
print("User has exceeded the rate limit.")
else:
print("User is within the rate limit.")
- 使用 Redis 的 Token Bucket 算法
import redis
import time
def token_bucket(redis_conn, user_id, rate, tokens, duration):
key = f"user:{user_id}:rate_limit"
now = time.time()
timestamp = redis_conn.get(key)
if timestamp:
timestamp = float(timestamp)
if now < timestamp:
return False
if now > timestamp + duration:
redis_conn.set(key, now, ex=duration)
redis_conn.set(f"{key}:tokens", max(tokens - (now - timestamp) * rate, 0))
else:
redis_conn.set(key, now, ex=duration)
redis_conn.set(f"{key}:tokens", tokens)
if redis_conn.exists(f"{key}:tokens"):
current_tokens = redis_conn.get(f"{key}:tokens")
if current_tokens and int(current_tokens) > 0:
redis_conn.decr(f"{ke
评论已关闭