요청 빈도 제한 및 안티패턴
Redis를 사용해 효과적인 요청 빈도 제한 메커니즘을 설계하고 구현하여 API와 서비스를 보호합니다.
요청 빈도 제한 및 안티패턴은(는) CoddyKit의 무료 Redis Caching & Messaging (Pub/Sub, Streams) 강의입니다. 이것은 4개 중 3번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 Redis Caching & Messaging (Pub/Sub, Streams) 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. Redis Caching & Messaging (Pub/Sub, Streams) 강의에는 총 4개의 강의가 포함되어 있습니다.
이 강의의 일부는 아직 번역되지 않았으며 영어로 표시됩니다.
Why Rate Limit?
Rate limiting is a crucial technique to control the frequency of requests an application receives. Think of it as a bouncer at a club, letting only a certain number of people in at a time.
It protects your APIs and services from:
- Abuse: Preventing malicious attacks like brute-force attempts.
- Overload: Ensuring your servers aren't overwhelmed by too many requests.
- Fair Usage: Distributing access fairly among all users.
Rate Limiting Concepts
When we talk about rate limiting, a few key terms come up:
- Limit: The maximum number of requests allowed.
- Window: The time period over which the limit applies (e.g., 60 seconds).
- Burst: A sudden spike in requests.
Different algorithms exist, like Fixed Window and Sliding Window, each with its own trade-offs.
Redis's Role in Rate Limiting
Redis is an excellent choice for implementing rate limiters due to its speed, in-memory nature, and atomic operations.
Its ability to quickly increment counters and set expirations makes it ideal for tracking request frequencies across a distributed system.
Fixed Window Algorithm
The Fixed Window algorithm is one of the simplest to implement. It works by:
- Defining a fixed time window (e.g., 60 seconds).
- Counting requests within that window.
- Blocking requests once the limit is reached.
At the end of each window, the counter resets. This method is straightforward but can allow bursts of requests at the window boundaries.
Fixed Window in Action
Here's how you can implement a basic fixed-window rate limiter using Redis's INCR and EXPIRE commands.
Try running this Python example:
import redis
import time
r = redis.Redis(decode_responses=True)
def check_rate_limit(user_id, limit_per_min):
key = f"rl:{user_id}"
# Increment counter for the user
current_count = r.incr(key)
# If it's the first request in this window, set expiration
if current_count == 1:
r.expire(key, 60) # Expire in 60 seconds
return current_count <= limit_per_min
if __name__ == "__main__":
test_user = "user_A"
rate_limit = 3 # 3 requests per minute
print(f"User '{test_user}' limit: {rate_limit} req/min")
for i in range(1, 6):
if check_rate_limit(test_user, rate_limit):
print(f"Request {i}: ALLOWED")
else:
print(f"Request {i}: BLOCKED")
time.sleep(0.5) # Simulate quick requests
print("\nWaiting for 60s window to reset...")
# In a real app, this delay would be handled by subsequent requests
# For demo, we'll clear the key
r.delete(f"rl:{test_user}")
time.sleep(1) # Small pause
print("Window reset. New request:")
if check_rate_limit(test_user, rate_limit):
print("Request 1: ALLOWED")
else:
print("Request 1: BLOCKED")Sliding Window Log Algorithm
The Sliding Window Log algorithm offers more accuracy by tracking individual request timestamps.
Here's how it works:
- Each request's timestamp is stored in a Redis Sorted Set (ZSET).
- When a new request arrives, old timestamps (outside the current window) are removed.
- The number of remaining timestamps in the ZSET is the current request count.
This method prevents the burst issue seen at fixed window boundaries.
Sliding Window Demo
Let's see the Sliding Window Log in action. We'll use Redis's ZADD to add timestamps and ZREMRANGEBYSCORE to remove old ones.
Try running this example:
import redis
import time
r = redis.Redis(decode_responses=True)
def check_sliding_window_limit(user_id, limit, window_seconds):
key = f"rl_sliding:{user_id}"
current_time = int(time.time() * 1000) # Milliseconds timestamp
# Remove scores older than the window
r.zremrangebyscore(key, 0, current_time - (window_seconds * 1000))
# Add current request timestamp
r.zadd(key, {current_time: current_time})
# Set expiration for the key itself to clean up old rate limiters
# This is a fallback if no new requests come for a long time
r.expire(key, window_seconds + 5)
# Count requests in the window
current_requests = r.zcard(key)
return current_requests <= limit
if __name__ == "__main__":
test_user = "user_B"
rate_limit = 3 # 3 requests per 10 seconds
window = 10 # seconds
print(f"User '{test_user}' limit: {rate_limit} req/{window}s (Sliding Log)")
for i in range(1, 6):
if check_sliding_window_limit(test_user, rate_limit, window):
print(f"Request {i}: ALLOWED")
else:
print(f"Request {i}: BLOCKED")
time.sleep(1) # Simulate requests over time
print("\nWaiting for window to slide...")
time.sleep(window)
print("Window slid. New request:")
if check_sliding_window_limit(test_user, rate_limit, window):
print("Request 1: ALLOWED")
else:
print("Request 1: BLOCKED")Common Pitfalls
When implementing rate limiting, avoid these common anti-patterns:
- Using
KEYS *: Never use this in production to find rate limit keys, as it can block your Redis server. - Ignoring Bursts: Simple fixed windows can allow many requests at window boundaries, which might still overload your service.
- Over-engineering: Don't make your rate limiting logic overly complex, as it can introduce bugs and performance overhead.
- No Client Feedback: Always return appropriate HTTP status codes (like
429 Too Many Requests) andRetry-Afterheaders.
Rate Limiting Best Practices
To build robust rate limiters with Redis:
- Atomic Operations: Always use atomic Redis commands like
INCR,ZADD, andEXPIREto prevent race conditions. - Set Expirations: Ensure your Redis keys have appropriate Time-To-Live (TTL) values to clean up old data.
- Choose Wisely: Select the right algorithm (fixed, sliding log, sliding counter) based on your accuracy and performance needs.
- Provide Feedback: Inform clients when they are rate-limited using standard HTTP responses.
- Monitor: Keep an eye on your rate limiters to ensure they are working as expected and not causing false positives or negatives.
Check Your Knowledge
You've learned about the Fixed Window algorithm. Now, let's test your understanding of the Redis commands involved.
Recap & Next Steps
In this lesson, we explored the critical role of rate limiting in protecting your services and ensuring fair usage. You learned how Redis's speed and atomic operations make it an ideal tool for this.
We covered two fundamental algorithms: the Fixed Window (using INCR and EXPIRE) and the more accurate Sliding Window Log (using ZADD and ZREMRANGEBYSCORE).
Remember to avoid common anti-patterns and follow best practices for robust rate limiting. Keep practicing these patterns to master them!
AI 튜터와 함께 Redis Caching & Messaging (Pub/Sub, Streams)을(를) 배우세요 — 무료
브라우저에서 실제 코드를 작성하고 실행하며, 24/7 AI 튜터로부터 즉각적인 도움을 받고, 웹이나 앱에서 중단한 부분부터 계속 학습하세요.
- 코스
- 12
- 레슨
- 48
자주 묻는 질문
“요청 빈도 제한 및 안티패턴” 강의는 무료인가요?
네 — “요청 빈도 제한 및 안티패턴” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 Redis Caching & Messaging (Pub/Sub, Streams) 강의 전체를 잠금 해제할 수 있습니다. Redis Caching & Messaging (Pub/Sub, Streams) 강의에는 총 4개의 강의가 포함되어 있습니다.
“요청 빈도 제한 및 안티패턴”에서 뭘 배우나요?
Redis를 사용해 효과적인 요청 빈도 제한 메커니즘을 설계하고 구현하여 API와 서비스를 보호합니다. 브라우저에서 직접 실행하는 실습 코드로 Redis Caching & Messaging (Pub/Sub, Streams)을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.
Redis Caching & Messaging (Pub/Sub, Streams)을(를) 시작하는 데 경험이 필요한가요?
사전 경험은 필요하지 않습니다. CoddyKit의 Redis Caching & Messaging (Pub/Sub, Streams)은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 4개 중 3번째 강의입니다.
“요청 빈도 제한 및 안티패턴” 강의는 얼마나 걸리나요?
대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.
이 Redis Caching & Messaging (Pub/Sub, Streams) 강의에서 코드를 작성하고 실행할 수 있나요?
네. 모든 Redis Caching & Messaging (Pub/Sub, Streams) 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.
이 강의의 모든 강의
- 고급 캐시 패턴
- Redis를 사용한 세션 관리
- 요청 빈도 제한 및 안티패턴
- 캐시 무효화 전략