////
Search
Duplicate
4️⃣

4장. 처리율 제한 장치의 설계

네트워크 시스템 상에서 처리율 제한 장치는 클라이언트 또는 서비스가 보내는 트래픽의 처리율을 제어하기 위한 장치다.
즉, API 요청 횟수가 제한 장치에 정의된 임계치를 넘어서면 추가로 도달한 모든 호출은 처리가 중단된다. 다음은 몇 가지 사례다.
사용자는 초당 2회 이상 글을 작성할 수 없다.
같은 IP 주소로는 하루에 10개 이상의 동일한 요청이 불가능하다.
같은 디바이스로는 주당 5회 이상 리워드를 요청할 수 없다.
이런 처리율 제한 장치를 두었을 때, 장점은 다음과 같다.
Dos 공격에 의한 자원 고갈 방지
비용절감
서버 과부하

1단계 문제 이해 및 설계 범위 설정

면접관이 처리율 제한 장치를 설계해야 한다고 했을 때, 우리는 각각 장, 단점을 가지는 다양한 알고리즘들을 고려할 수 있다.
이 역시, 장, 단점에 따라 적절히 결정할 수 있도록 요구사항을 분명하게 이해하는 과정이 필요하다.

대표적인 요구사항

설정된 처리율을 초과하는 요청을 제한할 수 있어야 한다.
HTTP 응답시간에 나쁜 영향을 주어서는 안 된다.
가능한 적은 메모리를 사용해야 한다.
분산형 처리율 제한이 가능해야 한다.
예외 처리를 적절히 해야 한다.
제한 장치에 장애가 생기더라도 전체 시스템에 영향을 주어서는 안 된다.

2단계 개략적 설계안 제시 및 동의 구하기

기본적인 클라이언트-서버 통신 모델에 적용시킨다고 가정하자.

처리율 제한 장치는 어디에 둘 것인가?

API 서버에 둘 수도 있고 미들웨어로 만들어 API 서버로 가능 요청을 통제하게끔 할 수 있다.
클라우드 마이크로서비스인 경우, 처리율 제한 장치는 보통 API 게이트웨이라 불리는 컴포넌트에 구현된다.

처리율 제한 알고리즘

토큰 버킷 알고리즘
정의
지정된 용량을 가지는 컨테이너로 이 버킷에는 사전 설정된 양의 토큰이 주기적으로 채워진다. 그리고 각 요청은 처리될 때마다 하나의 토큰을 사용한다.
요청이 도착하면 먼저 버킷에 충분한 토큰이 있는지 검사하게 된다.
장점
구현이 쉽다.
메모리 사용 측면에서도 효율적이다.
짧은 시간에 집중되는 트래픽도 처리 가능하다. 버킷에 남은 토큰이 있기만 하면 요청은 시스템에 전달될 것이다.
단점
이 알고리즘은 버킷 크기와 토큰 공급률이라는 두 개 인자를 가지고 있는데, 이 값을 적절하게 튜닝하는 것은 까다로운 일이 된다.
누출 버킷 알고리즘
정의
토큰 버킷 알고리즘과 유사하지만 요청 처리율이 고정되어 있다는 점이 다르다.
이는 보통 큐로 구현하며 동작 원리는 다음과 같다.
요청이 도착하면 큐가 가득 차 있는지 보며, 빈자리가 있는 경우, 큐에 요청을 추가한다.
큐가 가득 차 있는 경우 새요 청은 버린다.
지정된 시간마다 큐에서 요청을 꺼내어 처리한다.
누출 버킷 알고리즘은 다음 두 인자를 필요로 한다.
버킷 크기 : 큐 사이즈의 값
처리율 : 지정된 시간당 몇 개의 항목을 처리할 지 지정하는 값이다. 보통 초 단위로 표현한다.
장점
큐의 크기가 제한되어 있어 메모리 사용량 측면에서 효율적이다.
고정된 처리율을 가족 있으므로 안정적 출력이 필요한 경우 적합하다.
⇒ 안정적 출력?
단점
단시간에 트래픽이 몰리는 경우, 큐에는 오래된 요청들이 쌓이게 되고 최신 요청들은 버려지게 된다.
이 역시, 인자 튜닝 관련한 이슈가 있을 수 있다.
고정 윈도 카운터 알고리즘
정의
타임라인을 고정된 간격의 윈도라는 단위로 나누고, 각 윈도마다 카운터를 붙인다.
이 카운터는 요청이 접수될 때마다 1씩 증가하며, 카운터의 값이 임계치에 도달하는 경우, 새로운 요청은 새로운 윈도가 열리기까지 버려진다.
장점
메모리 효율이 좋다.
이해하기 쉽다.
윈도가 닫히는 시점에, 카운터를 초기화하는 방식은 특정한 트래픽 패턴을 처리하기에 적합하다.
단점
윈도 경계 부근에서 일시적으로 많은 트래픽이 몰리는 경우, 기대한 처리율보다 더 많은 양의 요청을 처리하게 된다.
윈도를 00초부터 1분 간격으로 정하고 5개를 처리한다고 했을 때,
요청이 55 ~ 05초 사이에 10개가 들어온다면 모두 처리가 된다. 이는 당초 1분마다 5개 씩 처리되기 바랬던 기존의 처리양의 2배를 처리하게 된다.
이동 윈도 로깅 알고리즘
정의
레디스의 정렬 집합 같은 캐시에 요청의 타임스탬프 데이터를 보관하고, 이를 처리에 사용하여 특정 트래픽이 몰림을 방지하는 알고리즘이다.
새 요청이 오면 만료된 타임스탬프는 제거한다. 만료된 타임스탬프는 그 값이 현재 윈도의 시작 시점보다 오래된 타임스탬프를 말한다.
요청의 타임스탬프를 로그에 추가하고, 로그의 크기가 허용치보다 같거나 작으면 요청을 시스템에 전달한다. 그렇지 않은 경우, 처리를 거부한다.
장점
어느 순간의 윈도를 보더라도, 허용되는 요청의 개수는 시스템의 처리율 한도를 넘지 않는다.
단점
메모리 효율이 좋지 않다. 거부된 요청의 타임스탬프도 저장해두기 때문이다.
이동 윈도 카운터 알고리즘
정의
고정 윈도 카운터와 이동 윈도 로깅 알고리즘을 결합한 것이다.
간략하게 말해서 요청이 발생할 때마다 현재 1분간의 요청 수 + (직전 1분간의 요청 수 * 이동 윈도와 직전 1분이 겹치는 비율)의 수로 윈도에 존재하는 요청을 계산한다.
만약 00초부터 1분간 윈도를 설정한다 가정하고 현재 0 ~ 1분 동안 요청 5개, 현재 1분 30초 요청 2개라고 하면
5 * 50% + 2 = 4.5가 된다. 반올림, 내림은 재량껏 결정하면 된다. 이 값이 현재 임계치, 즉, 분당 처리율 한도보다 낮거나 같으면 받아들인다.
장점
이전 시간대의 평균 처리율에 따라 현재 윈도의 상태를 계산하므로 짧은 시간동안 몰리는 트래픽에도 잘 대응한다.
메모리 효율이 좋다.
단점
직전 시간대에 도착한 요청이 균등하게 분포되어 있는 경우를 가정하고 추정치를 계산하기 때문에, 문제가 발생할 수 있다.

개략적인 아키텍처

처리율 제한 알고리즘이 제공해야 하는 기능은 단순하다. 얼마나 많은 요청이 접수되었는지를 추적할 수 있는 카운터를 추적 대상(IP 주소, 디바이스, 사용자 식별자 등)의 경로마다 두고 한도를 넘어서면 거부하는 것이다.
그렇다면 이 카운터는 어느 곳에 보관할 것인가? 일반적으로 처리 속도 때문에 메모리 상에 적재되어 있는 캐시 메모리가 적합할 것인데, 대표적으로 레디스를 자주 사용한다.

3단계 상세 설계

개략적 설계만으로 부족한 내용들을 설계하는 단계다. 대표적으로 다음과 같은 사항들을 결정해야 한다.
처리율 제한 규칙은 어떻게 만들어지고 어디에 저장되는가?
처리가 제한된 요청들은 어떻게 처리되는가?

처리율 제한 규칙

결국, 예외를 설정하는 부분이므로 사용자 시나리오를 고려하거나, 서버의 스펙을 고려하여 결정해야 한다.
따닥을 방지할 수도 있겠다.

처리율 한도 초과 트래픽의 처리

한도 제한에 걸리면 429 응답을 클라이언트에게 보내는 것이 일반적이나, 경우에 따라서는 한도 제한에 걸린 요청들을 큐에 저장해두고 추후 처리되도록 할 ㅜㅅ 있다.
커스텀 헤더를 제공하여 클라이언트에게 처리 가능한 요청의 수를 보내거나, 요청의 제한을 보내는 등의 작업이 가능하다.

상세 설계

처리율 제한 규칙은 디스크에 보관한다. 보통, 배포되는 시스템에 필요하므로 환경변수 파일로 관리하는 것이 적합할 것이다.
클라이언트가 요청을 서버에 보내면 요청을 미들웨어가 먼저 처리할 것이다.
처리율 제한 미들웨어는 제한 규칙과 관련한 변수들을 캐시에서 가져온다. 가져온 값들에 근거하여 다음과 같은 결정을 내린다.
해당 요청이 처리율 제한에 걸리는 경우, 429나 메시지 큐에 보관한다.
그렇지 않은 경우, 요청을 처리한다.

분산 환경에서의 처리율 제한 장치 구현

분산 환경의 경우, 고려해야할 사항이 더 추가된다. 일반적으로 다음 두 가지를 더 고려해야 한다.
경쟁 조건
동기화

경쟁 조건

레디스나 메모리에 카운터를 저장해두고 사용하는 경우, 해당할 것이다.
락을 사용하는 것이 대표적이며 락 대신 사용할 수 있는 방안으론 루아 슼릡트, 정렬 집합을 사용하는 것이다.

동기화 이슈

처리율 제한 장치를 여럿 두게 되는 경우, 발생할 수 있는 문제다.
처리율 제한 장치가 참조하는 레디스를 중앙 집중형으로 설계하여 방지할 수 있다.

성능 최적화

두 가지 지점에서 개선 시도가 가능하다.
처리율 제한 장치의 지연시간을 줄이기 위해 물리적으로 근거리에 처리율 제한 장치를 둔다.
제한 장치 간의 동기화를 위해 최종 일관성 모델을 사용한다.
이는, 6장의 키-값 저장소 설계에서 데이터 일관성을 참고하자.

모니터링

기본적으로 처리율 제한 장치를 모니터링함으로써 얻고자 하는 정보들은 다음과 같다.
채택된 처리율 제한 알고리즘이 효과적인지
정의한 처리율 제한 규칙이 효과적인지
모니터링을 위해 해당 정보들을 제공하면서 적절히 튜닝할 수 있도록 해야 한다.

4단계 마무리

처리율 제한을 구현하는 알고리즘과 그 장, 단점들을 다뤘으며 알고리즘 외에도 아키텍처, 분산환경에서의 처리율 제한 장치, 성능 최적화, 모니터링 등을 다뤘다.
다음과 같은 부분을 추가적으로 찾아보면 개선할 부분을 찾을 수 있을 것이다.
경성 또는 연성 처리율 제한
경성 처리율 제한 : 요청의 개수는 임계치를 넘을 수 없다.
연성 처리율 제한 : 요청의 개수는 잠시 동안만은 임계치를 넘을 수도 있다.
다양한 계층에서의 처리율 제한
애플리케이션 계층이 아닌, 계층에서의 처리율 제한을 시도해볼 수 있다.
Iptables를 사용한 IP 주소에 처리율 제한을 거는 등 말이다.
처리율 제한을 회피하기 위해 클라이언트 측의 설계를 고려해볼 수 있다.
클라이언트 측 캐시를 사용하여 API 호출 횟수를 줄인다던가.
임계치를 이해하고 클라이언트 측에서 API 호출을 제어한다던가.
재시도 로직을 구현하는 경우, 충분한 재시도 시간을 튜닝한다던가.