Rate limiting vs Throttling

dj-yang·2022년 1월 15일
0

서론

팀 내에서 진행하는 토론에 ratelimit, throttling이라는 용어가 나왔지만.. 재밌게도 난 둘 다 제대로 알지는 못 하는 개념이기 때문에 조용히 있을 수 밖에 없었다.

어떤 개념인지를 파악하기 위해 검색을 진행하고 그 내용을 여기에 정리했다.


본론

Rate Limiting

ratelimit에 대해서 인터넷 검색을 진행했을 때 아래와 같은 글들이 있었다.

Rate Limiting is a client side response to the maximum capacity of a channel. If a channel has capacity to consume requests at a given rate/sec then a client should be prepared to limit their request rate

위의 글 내용을 확인해보면 'client side의 채널 이용에 제한을 두는 방식'으로 귀결되는 것 같다. 즉 client가 request를 보낼 수 있는 횟수를 제한하는 방식인 것으로 이해했다. 이와 같은 방식을 사용하는 이유에 대해서 찾아봤는데

In computer networks, rate limiting is used to control the rate of requests sent or received by a network interface controller. It can be used to prevent DoS attacks and limit web scraping.

출처: https://en.wikipedia.org/wiki/Rate_limiting

즉 Dos나 web scraping을 방지하는 하기 위해서라고 한다.

정리하자면 Rate Limiting을 적용하는 목적을 대표적으로 뽑아보면 아래와 같은 것 같다.

  1. 즉 Dos나 web scraping을 방비
  2. 서비스의 가용성(API레벨, 네트워크 레벨, 컨테이너 레벨, CPU 레벨 등) 유지

Rate Limiting을 적용하기 위한 5가지 알고리즘이 있다.

1. Leaky Bucket

네트워크로의 데이터 주입 속도의 상한을 정해 제어하고 네트워크에서 트래픽 체증을 일정하게 유지한다. 일정한 유출 속도(유출 속도는 고정된 값)를 제한하여 버스트 유입 속도를 부드럽게 한다.

  • 고정 용량의 버킷에 다양한 유량의 물이 들어오면 버킷에 담기고 그 담긴물은 일정량 비율로 떨어진다.
  • 들어오는 물의 양이 많아 버킷의 용량을 초과하게 되면 그 물은 버린다.
  • 입력 속도가 출력 속도보다 크면 버킷에서 누적이 발생하고 누적이 버킷 용량보다 큰 경우 오버플로가 발생하여 데이터 패킷 손실이 발생할 수 있다.

2. Token Bucket

일시적으로 많은 트래픽이 와도 토큰이 있다면 처리가 가능하면서 토큰 손실 처리를 통해 평균 처리 속도를 제한할 수 있다. 즉, 평균 유입 속도를 제한하고 처리 패킷 손실없이 특정 수준의 버스트 요청 허용할 수 있다.

  • 토큰은 정해진 비율로 토큰 버킷에 넣는다.
  • 버킷은 최대 n개의 토큰을 저장하며, 버킷이 가득차면 새로 추가된 토큰은 삭제되거나 거부된다.
  • 요청이 들어오면 큐에 들어가며 요청을 처리하기 전에 토큰 버킷의 토큰을 획득해야 하며, 토큰을 보유한 후에 요청이 처리되며 처리된 후에는 토큰을 삭제한다.
  • 토큰 버킷은 토큰이 배치되는 속도를 기반으로 액세스 속도를 제어한다.
  • 전송 횟수를 누적할 수 있으며, 버킷이 가득차면 패킷 손실 없이 토큰이 손실된다.

3. Fixed Window Counter

정해진 시간 단위로 window가 만들어지고 요청 건수가 기록되어 해당 window의 요청 건수가 정해진 건수보다 크면 해당 요청은 처리가 거부된다. 이 알고리즘을 사용하면 경계의 시간대(12:59, 13:01초에 몰리면)에 요청이 오면 두배의 부하를 받게 된다. 즉, 구현은 쉽지만, 기간 경계의 트래픽 편향 문제가 발생된다.

  • 버킷에는 정해진 시간 단위의 window(window 1번은 12:00 - 13:00, window 2번은 13:00 - 14:00)가 존재하고 시간 단위의 각 window는 요청이 오면 요청 건수가 기록된다.
  • 시간당 정해진 요청 건수가 초과(여기서는 분당 4건이 상한)되는 9번의 요청은 거부된다.

4. Sliding Window Log

Fixed window counter의 단점인 기간 경계의 편향에 대응하기 위한 알고리즘이다. 하지만, window의 요청건에 대한 로그를 관리해야하기 때문에 구현과 메모리 비용이 높은 문제점이 있다.

  • 분당 2건의 요청을 처리한다면 12초와 24초에 온 요청은 허용이 되고 36초에 온 요청 분당 2건처리 원칙에 의해 거부되고
  • 1분 25초의 요청이 들어오면 12초와 14초에 온 요청 로그를 pop해서 꺼내 없애고 남은 건 바로 전 요청인 36초에 온거 하나만 있어서 1분 25초에 들어온 요청은 처리가 된다.

5. Sliding Window Counter

Fixed window counter의 경계 문제와 Sliding window log의 로그 보관 비용 등의 문제점을 보완할 수 있는 알고리즘이다.

  • 분당 10건 처리한다면 1분안에 9건의 요청이 오고 1분과 2분 사이에는 5건이 요청온다고 가정.
  • 1분 15초에 요청이 왔는데 1분 15초 지점은 1분과 2분 사이에서 25% 지점, 이전 기간은 1 - 0.25 = 75% 비율로 계산해서 9 * 0.75 + 5 = 14.75 > 10으로 한도를 초과했기 때문에 요청은 거부된다. 즉, 이전 window와 현재 window의 비율값으로 계산된 합이 처리 건수를 초과하면 거부된다.
  • 1분 30초 시점에 요청이 온다면 이전 기간은 50%, 9 * 0.5 + 5 = 9.5 < 10이므로 해당 요청은 처리된다.

Sliding Window Counter는 window의 비율이 소수점이 나오게 되면 정확성이 떨어질 수는 있으나, Fixed window counter의 경계 문제와 Sliding window log의 로그 보관 비용 등의 문제점을 개선하게 된다.

Rate Limiting 적용 시 고려 사항

  • Rate Limit 알고리즘은 트래픽 패턴을 잘 분석한 다음 적합한 알고리즘을 선택해야 한다. 유료 서비스가 트래픽 체증에 민감해하지 않다면(관대한) Token Bucket 알고리즘을 선택하고 그 외에는 Fixed Wondow나 Sliding Window 알고리즘을 선택한다.
  • 기본적으로 서비스 인프라 트래픽을 수용할 수 없는 시점에 도달했을 때 Rate Limit을 적용해야하며, 외부 서비스에 영향을 최소화하는 노력(Common한 API는 Rate Limit에 걸리지 않을 정도로 상한값을 높게 잡음 등)을 한 다음 Rate Limit을 적용하는게 좋다.
  • 외부 개발자들에게 Rate Limit 정보를 명확하게 알려야하고, API 응답에도 요청 정보와 남은 정보 등 트래픽이 초과했을때 오류값 등을 명확히 정의해야 한다.

Throttling

PC, 노트북, 모바일 기기의 CPU, GPU 등이 지나치게 과열될때 기기의 손상을 막고자 클럭과 전압을 강제적으로 낮추거나 강제로 전원을 꺼서 발열을 줄이는 기능이다.

출처: https://12bme.tistory.com/504 [길은 가면, 뒤에 있다.]

말 그대로 특정 하드웨어(우리에게는 서버)의 성능을 넘어서는 작업이 진행될 때 해당 부분을 다양한 방식으로 조정해 서비스 가용성을 유지하는 것을 뜻하는 것 같다.

결론

나는 2가지에 대해서 이야기할 때 어떤 것이 우리 서비스에 맞을까 생각을 진행했는데 멍청한 고민이었던 것 같다. 그 이유는 아래 글을 확인하면 이해할 수 있다.

“Throttling, also sometimes called Rate Limiting, is a technique that allows a service to control the consumption of resources used by an instance of an application, an individual tenant, or an entire service”

출처 : https://beabetterdev.com/2020/12/12/what-is-api-throttling-and-rate-limiting/

때때로 Rate Limiting이라고 불리는 Throttling은..

결국 같은 것을 다르게 표현하는 것 같고 개인적으로 쓸데 없는 첨언을 하자면 Throttling이라는 개념이 조금 더 넓은 의미에서 사용하는 개념이 아닌가 싶다.

예를 들어 "우리는 특정 부분에서 서버의 가용성을 떨어지는 것을 발견했고 Throttling이라는 개념을 적용할 필요가 있는데 그 부분에 적용할 방식으로는 Rate Limiting이 적절하다" 라고 표현하면 가장 알맞은 표현인 것 같다.

마지막으로 위의 인용문을 가져온 페이지에서 눈에 띈 문장으로 끝내려고 한다.

"Throttling is a policy that the Server enforces and the Client respects."

"Throttling은 서버에서 강제하고 클라이언트에서 준수하는 정책이다."


Rate Limiting 파트에서 사용하는 이미지 및 텍스트는 https://www.progress.com/blogs/how-to-rate-limit-an-api-query-throttling-made-easy 에서 가져왔습니다.

profile
비전공자가 고통받으며 개발합니다

0개의 댓글