Database/Redis

[Redis] Usecase: Rate Limiter

noahkim_ 2026. 8. 12. 15:17

1. Rate Limiter란?

  • 특정 사용자나 IP 등이 일정 시간 동안 보낼 수 있는 요청 수를 제한하는 기능

 

역할

역할 설명
과도한 트래픽 방지 요청량을 제한하여 서버에 과도한 부하가 발생하는 것을 방지
악의적인 요청 방어 비정상적인 반복 요청이나 API 남용으로부터 시스템 보호
특정 사용자의 자원 독점 방지 사용자별 요청량을 제한하여 일부 사용자가 시스템 자원을 과도하게 사용하는 것을 방지
DB 및 외부 API 보호 요청 폭증이 DB, Redis, 외부 API 등 Downstream 시스템으로 전파되는 것을 방지
트래픽 급증 시 시스템 안정성 확보 순간적인 요청 증가를 제어하여 전체 서비스의 안정적인 운영 지원

 

제한 기준

  • Redis에는 Rate Limit의 기준이 되는 Key가 만들어짐
  • ✅ 누구를 제한할 것인지를 Key로 표현함
  • ex) userId, IP, API KEY, Tenant, 전체 시스템

 

ex) Redis Rate Limit Key

더보기
제한 대상 Key 예시
사용자 user:123
IP ip:192.168.0.10
API Key api-key:abc123
Tenant tenant:company-a
API별 사용자 api:chat:user:123
전체 시스템 global:api

 

2. Token Bucket

  • 토큰이 들어있는 Bucket을 두고, 요청 하나를 처리할 때마다 토큰을 소비하는 방식
  •  시간이 지나면서 토큰이 다시 충전됨
  • ✅ capacity, refillRate, refillInterval 등의 정책을 사용함
  • ➡️ Burst Traffic을 일정 수준 허용하면서 장기적인 평균 요청량을 제한할 수 있음

 

Hash 자료구조로 저장하기

  • Key: user:123
  • Value: tokens = 7, last_refill = 1723440000

 

동작 흐름

  1. 현재 Token 확인 (첫 요청이면 Bucket 생성)
  2. 마지막 충전 이후 얼마나 시간이 지났는지 계산 (현재 시간 - last_refill)
  3. Token 충전 (흐른시간에 refillRate를 곱해 추가함. capacity 상한선까지 증가 가능)
  4. Token 사용 (1개 이상 있어야 사용가능)
  5. 새로운 상태 Redis에 저장 (tokens, last_refill 갱신)
  6. 허용/거부 결과 반환 (allowed + remained tokens or denied)

 

Race Condition

  • ⚠️ tokens=1인 상태에서 동시에 요청이 들어올 경우, 둘다 성공함
  • ➡️ Lua Script를 사용하여 "읽기 + 계산 + 토큰 차감 + 기록" 을 원자적으로 처리함

 

3. 전체 요청 흐름

  • 성공: "User 123" 요청 → API Gateway → Rate Limiter → Redis (ALLOW) → Backend
  • 실패: "User 123" 요청 → API Gateway → Rate Limiter → Redis (DENY) → 429 Too Many Requests

 

Response Header

Header 의미
X-RateLimit-Limit 전체 허용량 또는 제한 기준
X-RateLimit-Remaining 현재 남은 요청 가능량
Retry-After 제한된 경우 다시 요청하기까지 기다려야 할 시간

 

 

출처