Skip to content

Rate limiting

컴퓨터 네트워크에서 속도 제한은 네트워크 인터페이스 컨트롤러에서 보내거나 받는 요청의 속도를 제어하는 ​​데 사용됩니다. DoS 공격을 방지하고 웹 스크래핑을 제한하는 데 사용할 수 있습니다.

왜 Rate Limit(사용량 제한)이 필요한가?

  • 많은 참여자가 있는 트위치 채팅에서 스패머 한 명이 있을 때, 사용량 제한이 없다면 스패머가 대화를 지배할 수 있음.
  • 사용량 제한을 통해 각 사용자가 공정하게 참여할 기회를 가질 수 있음.
  • Rate Limiter(사용량 제한기)는 특정 기간 동안 설정된 한도를 초과하는 요청을 차단하여 서비스의 트래픽을 제어함. 이는 채팅에서의 스팸 조절 외에도 유용함
  • 예를 들어, 로그인 폼에서 사용량 제한을 통해 브루트 포스 공격을 억제하면서도 소량의 잘못된 추측을 허용할 수 있음
  • API 엔드포인트도 종종 사용량 제한이 적용되어 단일 사용자가 리소스를 독점하지 못하게 함
    • 사용자가 비싼 API 엔드포인트를 분당 100번만 호출할 수 있도록 하면 카운터를 사용하여 분당 100번의 히트를 추적하고, 그 후의 요청은 차단
    • 이는 가장 간단한 사용량 제한 알고리듬 중 하나인 고정 윈도우 제한기(Fixed Window Limiter)임
    • 서비스 트래픽을 제어하는 일반적인 방법

Leaky Bucket

FIFO 형식의 Bucket(Queue)에 요청을 차례로 담아 크기가 다 차면 요청 제한

Fixed windows 알고리듬

  • 고정된 시간 창(window) 내에서 요청 수가 제한됨
  • 각 시간 창의 시작에 요청 카운터가 0으로 재설정됨
  • 장점
    • 구현과 이해가 쉬움
    • 사용자에게 예측 가능함
  • 단점
    • 시간 창 끝 무렵에 요청이 시작되면 제한의 최대 2배까지 요청 폭증(burst)이 허용될 수 있음
  • 실제 사례: GitHub API는 시간당 5,000개의 요청을 허용하는 고정 시간 창 속도 제한기를 사용함
  • 시간 창의 시작 시간을 고정된 간격으로 설정하는 대신, 각 시간 창은 해당 시간 창 내에서 사용자의 첫 번째 요청 시점에 생성될 수 있음
  • 이 접근 방식에서는 다음 시간 창까지 남은 시간을 사용자에게 알려주는 것이 특히 중요함

슬라이딩 윈도우(Sliding windows) 알고리듬

  • 용량을 한 번에 모두 새로 고치는 대신, 슬라이딩 윈도우는 한 번에 하나의 요청씩 용량을 채움
  • 장점
    • 요청 트래픽의 분포를 부드럽게 함
    • 높은 부하에 적합함
  • 단점
    • 고정 시간 창보다 사용자에게 예측 가능성이 떨어짐
    • 각 요청의 타임스탬프를 저장하는 것은 리소스 집약적임
  • 높은 트래픽 시나리오에서 슬라이딩 윈도우가 가장 유용하기 때문에, 기본 알고리듬이 리소스 집약적이라는 사실은 역효과를 낳음
  • 따라서 대부분의 실제 슬라이딩 윈도우 속도 제한기는 근사 방식(approximation)을 사용함
  • 근사 방식은 이전 고정 시간 창에서 허용된 요청 수와 현재 고정 시간 창에서 허용된 요청 수를 계산하고, 이전 시간 창의 허용된 요청을 현재 시간에 끝나는 부동 시간 창과의 중첩에 비례하여 가중치를 부여함
  • 이 근사 방식은 요청을 거의 동일한 비율로 제한하지만 훨씬 더 효율적임
  • 실제 사례: Cloudflare의 구성 가능한 속도 제한기는 근사 슬라이딩 윈도우를 사용함

토큰 버킷(Token buckets) 알고리듬

  • 시간 창의 지속 시간 대신, 일정한 속도로 "토큰"으로 채워지는 버킷을 상상함
  • 각 요청은 이 버킷에서 하나의 토큰을 인출하고, 버킷이 비어 있으면 다음 요청이 차단됨
  • 버킷의 용량은 버스트가 지원할 수 있는 최대 요청 수를 나타냄
  • 보충 간격은 장기 평균 허용 요청 간격을 나타냄
  • 여러 개의 속도 제한기 없이 별개의 버스트 및 평균 용량을 가질 수 있다는 것이 이 알고리듬의 주요 이점 중 하나임
  • 장점
    • 높은 트래픽의 버스트를 허용하지만 장기 평균 요청 속도를 적용함
    • 사용자에게 더 유연하여 허용 가능한 범위 내에서 트래픽 급증을 허용함
  • 단점
    • 고정 시간 창보다 사용자에게 제한 사항과 보충 시간을 전달하기가 더 어려움
  • 실제 사례
    • Stripe는 사용자당 500개의 제한과 0.01초의 보충 간격을 가진 토큰 버킷을 사용하여 초당 100개의 요청을 지속적으로 허용하지만 최대 500개의 요청까지 버스트를 허용함
    • OpenAI의 GPT-3.5 무료 티어는 200개의 제한과 86400초/200의 보충 간격을 가진 토큰 버킷을 사용하여 하루에 200개의 요청으로 제한됨

레이트 리밋 적용 시 고려 사항

  • 레이트 리미터에 대한 영구 저장소를 만들어야 함
  • 영구 저장소에 대한 서버의 연결이 실패하면 요청을 차단하지 않고 모두 허용하도록 해야 함
  • 선택적으로 버스트 트래픽을 조절할 수 있음
  • 적절한 키를 선택해야 함 (사용자 ID, API 키 등)
  • 유용한 속도 제한 오류를 표시해야 함 (다음 요청까지 대기 시간, 429 HTTP 상태 코드, x-ratelimit-* 응답 헤더 등)

See also

Favorite site