[대규모 시스템 설계 스터디] 4장 정리

김연준·2026년 7월 23일
post-thumbnail

처리율 제한 장치

1. 처리율 제한 장치란

  • 클라이언트 또는 서비스가 보내는 트래픽의 처리율을 제어하는 장치
  • 일정 시간 동안 허용되는 요청 수를 제한하는 방식
  • 웹 서버, API 게이트웨이, 로드밸런서, 방화벽 등에 프로그램 로직으로 구현 가능

2. 처리율 제한 장치의 장점

2.1 DoS 공격으로 인한 자원 고갈 방지

  • 과도한 요청으로부터 서버 자원 보호
  • CPU, 메모리, 네트워크, 데이터베이스 연결 등의 고갈 방지
  • 악의적인 요청뿐 아니라 비정상적인 클라이언트 동작에도 대응 가능

2.2 비용 절감

  • 불필요한 서버 확장 방지
  • 유료 외부 API 호출 횟수 제한
  • 처리 가능한 요청만 백엔드 서비스로 전달

2.3 서버 과부하 방지

  • 서버가 처리할 수 있는 수준으로 요청량 조절
  • 급격한 트래픽 증가로 인한 장애 방지
  • 서비스 안정성 및 응답 시간 유지

3. 처리율 제한 방식

처리율 제한은 요청 속도를 제어하는 주체에 따라 클라이언트 측 제한과 서버 측 제한으로 구분 가능

3.1 클라이언트 측 제한

  • 요청을 보내는 클라이언트가 자체적으로 요청 속도를 조절하는 방식

  • 대표적인 방법

    • 디바운싱
    • 스로틀링
    • 재시도 간격 조절
  • 서버 부담 감소 가능

  • 불필요한 네트워크 요청 감소 가능

  • 클라이언트 프로그램의 수정 또는 우회 가능

  • 보안 목적의 처리율 제한 수단으로는 신뢰하기 어려움

3.2 서버 측 제한

  • 서버가 들어오는 요청을 직접 검사하고 제한하는 방식

  • 다음과 같은 기준으로 제한 가능

    • IP 주소
    • 사용자 계정
    • API 키
    • 특정 API 경로
    • 일정 시간 동안의 요청 횟수
  • 클라이언트가 임의로 우회하기 어려움

  • 실제 서비스 보호를 위해 필요한 방식

3.3 클라이언트 측 제한과 서버 측 제한의 병행

  • 실제 서비스에서는 두 방식을 함께 적용 가능

  • 클라이언트 측 제한

    • 불필요한 요청 발생 억제
    • 사용자 경험 및 네트워크 효율 개선
  • 서버 측 제한

    • 클라이언트의 우회 또는 비정상 동작으로부터 시스템 보호
    • 최종적인 처리율 제한 정책 강제

4. 시스템 요구사항

4.1 기능 요구사항

  • 서버 측 API를 위한 처리율 제한 장치 설계
  • 다양한 형태의 제어 규칙 지원
  • 요청 제한 시 클라이언트에게 제한 사실 전달
  • 서비스별 처리율 제한 정책 설정 지원

4.2 비기능 요구사항

  • 대규모 요청 처리 가능
  • 가능한 한 적은 메모리 사용
  • 분산 환경에서 동작
  • 높은 가용성 확보
  • 처리율 제한 기능으로 인한 응답 지연 최소화

4.3 배포 방식

  • 처리율 제한 장치를 독립된 서비스로 구현 가능
  • 애플리케이션 서버 또는 API 게이트웨이에 종속된 기능으로 구현 가능
  • 시스템 환경, 운영 규모, 성능 요구사항에 따라 적절한 방식 선택 필요

독립된 서비스로 구현하는 경우

  • 여러 서비스의 처리율 제한 정책을 중앙에서 관리 가능
  • 처리율 제한 로직을 각 애플리케이션과 분리 가능
  • 여러 서비스에서 공통 기능으로 재사용 가능
  • 처리율 제한 기능만 독립적으로 확장하거나 배포 가능

애플리케이션 또는 API 게이트웨이에 포함하는 경우

  • 별도의 네트워크 호출이 필요하지 않아 지연 시간 감소 가능
  • 시스템 구성과 운영 복잡도 감소
  • 애플리케이션 또는 게이트웨이의 기존 인증·라우팅 정보 활용 가능
  • 소규모 시스템이나 서비스별 정책이 다른 환경에 적용하기 쉬움

선택 시 고려 사항

  • 독립된 서비스는 중앙 관리와 재사용에 유리하지만 추가적인 네트워크 지연과 장애 지점 발생 가능

  • 종속된 방식은 구현이 단순하지만 서비스마다 로직이 중복될 가능성 존재

  • 독립 여부와 관계없이 처리율 제한 장치 장애에 대한 정책 필요

    • 장애 발생 시 요청을 허용하는 fail-open
    • 장애 발생 시 요청을 차단하는 fail-closed

5. API 게이트웨이와 처리율 제한

5.1 API 게이트웨이의 역할

  • 클라이언트와 백엔드 서비스 사이에서 API 요청을 중계하는 컴포넌트

  • 여러 서비스에 공통으로 필요한 기능 처리

    • 요청 라우팅
    • 처리율 제한
    • 사용자 인증 및 인가
    • SSL/TLS 종단
    • API 키 검증
    • 로깅 및 모니터링
  • 처리율 제한은 API 게이트웨이가 제공할 수 있는 기능 중 하나임

5.2 완전 관리형 API 게이트웨이

  • 클라우드 사업자가 API 게이트웨이를 완전 관리형 서비스로 제공하는 경우가 많음
  • 서버 설치와 운영 부담 감소
  • 처리율 제한, 인증, 모니터링 등의 기능을 설정 방식으로 적용 가능
  • 사용하는 제품에 따라 지원 기능과 처리율 제한 알고리즘에 차이 발생 가능

5.3 MSA에서의 활용

  • MSA에서는 처리율 제한 장치를 API 게이트웨이에 구현하는 경우가 많음
  • 클라이언트 요청이 각 마이크로서비스에 도달하기 전에 공통 정책 적용 가능
  • 각 마이크로서비스에 처리율 제한 로직을 중복 구현하는 문제 감소
  • 서비스 전체의 처리율 제한 정책을 중앙에서 관리 가능

5.4 처리율 제한 장치의 위치를 결정할 때 고려할 사항

  • 처리율 제한 장치를 어디에 배치할지는 서비스 상황과 목표에 따라 결정
  • 모든 시스템에 적용되는 단일한 정답은 없음

구현 환경

  • 현재 사용하는 프로그래밍 언어와 프레임워크가 서버 측 처리율 제한 구현에 적합한지 확인
  • 높은 요청량에서도 충분한 성능을 제공할 수 있는지 확인

알고리즘 선택권

  • 직접 구현할 경우 필요한 알고리즘을 자유롭게 선택 가능
  • 외부 API 게이트웨이를 사용할 경우 제공되는 알고리즘과 설정 방식에 제약 발생 가능

기존 아키텍처

  • MSA에 API 게이트웨이가 이미 포함된 경우 게이트웨이에 처리율 제한 기능 추가 가능
  • 공통 정책의 중앙 관리 가능

개발 및 운영 인력

  • 직접 구현하고 운영할 인력이 부족한 경우 상용 API 게이트웨이 활용 가능
  • 개발 비용과 운영 복잡도 감소 가능

6. 처리율 제한 알고리즘

  • 토큰 버킷
  • 누출 버킷
  • 고정 윈도 카운터
  • 이동 윈도 로그
  • 이동 윈도 카운터

7. 토큰 버킷 알고리즘

7.1 기본 개념

  • 지정된 용량을 갖는 버킷 사용
  • 버킷 내부에 요청 처리 권한을 의미하는 토큰 저장
  • 사전에 설정된 공급률에 따라 토큰 추가
  • 버킷이 가득 찬 경우 추가 토큰 폐기

7.2 동작 원리

  1. 요청 도착
  2. 버킷에 토큰이 있는지 확인
  3. 토큰이 있으면 토큰 하나 소비
  4. 요청을 시스템에 전달
  5. 토큰이 없으면 요청 거부 또는 폐기

7.3 주요 인자

버킷 크기

  • 버킷에 저장할 수 있는 토큰의 최대 개수
  • 순간적으로 허용할 수 있는 최대 요청량과 관련됨

토큰 공급률

  • 일정 시간 마다 버킷에 추가되는 토큰 수
  • 장기적으로 허용되는 평균 요청 처리율과 관련됨

7.4 버킷 구성

  • 제한 정책에 따라 별도의 버킷 구성 가능

  • 버킷을 구분할 수 있는 기준

    • 사용자
    • IP 주소
    • API 키
    • API 엔드포인트
    • 서비스
  • 사용자 ID + API 경로처럼 여러 기준을 조합하여 버킷을 구분할 수도 있음

7.5 장점

  • 구현이 비교적 간단함
  • 메모리 사용량이 적음
  • 일정 범위의 순간적인 트래픽 증가 허용 가능
  • 평균 처리율을 유지하면서 버스트 트래픽 처리 가능

7.6 단점

  • 버킷 크기와 토큰 공급률의 적절한 설정이 어려움
  • 잘못된 인자 설정 시 정상 요청이 과도하게 거부될 수 있음

8. 누출 버킷 알고리즘

8.1 기본 개념

  • 요청을 큐에 저장한 후 일정한 속도로 처리
  • 일반적으로 FIFO 큐로 구현
  • 출력 처리율이 일정하게 유지됨

8.2 동작 원리

  1. 요청 도착
  2. 큐에 빈자리가 있는지 확인
  3. 빈자리가 있으면 요청을 큐에 추가
  4. 큐가 가득 찬 경우 새로운 요청 폐기
  5. 일정한 주기마다 큐에서 요청을 꺼내 처리

8.3 주요 인자

버킷 크기

  • 요청을 저장하는 큐의 최대 크기

처리율

  • 일정 시간 동안 큐에서 처리하는 요청 수
  • 일반적으로 초 단위로 설정

8.4 토큰 버킷과의 차이

  • 토큰 버킷

    • 토큰이 남아 있으면 순간적인 요청 증가 허용
  • 누출 버킷

    • 요청을 일정한 속도로 꺼내 처리
    • 출력 처리율이 상대적으로 일정함

8.5 장점

  • 큐 크기가 제한되어 있어 메모리 사용량 예측 가능
  • 일정한 출력 처리율 제공
  • 안정적인 요청 처리 속도가 필요한 시스템에 적합

8.6 단점

  • 단시간에 트래픽이 몰리면 큐에 오래된 요청 누적
  • 큐가 가득 차면 새로운 요청 폐기
  • 큐 크기와 처리율 설정이 어려움
  • 큐 대기로 인해 응답 지연 증가 가능

9. 고정 윈도 카운터 알고리즘

9.1 기본 개념

  • 시간을 일정한 크기의 고정 구간으로 분할
  • 각 구간마다 요청 수를 기록하는 카운터 사용

9.2 동작 원리

  1. 요청 도착
  2. 현재 윈도의 카운터를 1 증가
  3. 카운터가 설정된 한도 이하이면 요청 허용
  4. 한도를 초과하면 새로운 윈도가 시작될 때까지 요청 거부
  5. 새로운 윈도가 시작되면 카운터 초기화

9.3 장점

  • 구현이 간단함
  • 이해하기 쉬움
  • 카운터 하나만 저장하면 되므로 메모리 효율이 높음
  • 일정한 시간 단위로 요청량을 관리하는 정책에 적합

9.4 단점

  • 윈도 경계에서 처리율 한도를 초과할 수 있음
  • 이전 윈도 마지막 시점과 다음 윈도 시작 시점에 요청이 집중될 경우 문제 발생
  • 실제 연속 시간 기준으로는 설정한 한도보다 많은 요청 허용 가능

10. 이동 윈도 로그 알고리즘

10.1 기본 개념

  • 각 요청의 타임스탬프를 개별적으로 기록
  • Redis 정렬 집합과 같은 자료구조 활용 가능

10.2 동작 원리

  1. 새로운 요청 도착
  2. 현재 윈도의 시작 시점보다 오래된 타임스탬프 제거
  3. 새로운 요청의 타임스탬프를 로그에 추가
  4. 로그에 저장된 요청 수 확인
  5. 요청 수가 허용치 이하이면 요청 전달
  6. 허용치를 초과하면 요청 거부

10.3 장점

  • 고정 윈도 카운터의 경계 문제 해결
  • 현재 시점을 기준으로 정확한 시간 범위 계산 가능
  • 어느 시점에서 윈도를 계산해도 요청 수가 설정 한도를 넘지 않도록 제어 가능

10.4 단점

  • 각 요청의 타임스탬프를 저장해야 함
  • 요청량이 많을수록 메모리 사용량 증가
  • 거부된 요청의 타임스탬프까지 저장하는 구현에서는 추가 메모리 사용 발생

11. 이동 윈도 카운터 알고리즘

11.1 기본 개념

  • 고정 윈도 카운터와 이동 윈도 로그의 특징을 결합한 방식
  • 현재 윈도와 직전 윈도의 카운터를 이용하여 현재 시간 범위의 요청 수 추정

11.2 동작 원리

  • 예를 들어 시간을 1분 단위의 고정 구간으로 분할
  • 이전 1분 구간과 현재 1분 구간의 요청 수 저장
  • 이전 구간의 요청을 모두 포함하지 않음
  • 현재 시점과 가까운 부분만 시간 비율에 따라 반영
  • 직전 윈도의 요청이 윈도 전체에 균등하게 분포한다고 가정

11.3 계산 예시

  • 처리율 제한: 분당 100개
  • 현재 시각: 현재 윈도가 시작된 후 20초 경과
  • 직전 윈도 요청 수: 90개
  • 현재 윈도 요청 수: 30개
  • 직전 윈도에서 현재 이동 윈도와 겹치는 비율: 40초 ÷ 60초
  • 추정 요청 수

90 × (40 ÷ 60) + 30 = 90개

11.4 장점

  • 이전 시간대의 평균 처리율에 따라 현재 윈도의 상태 계산
  • 짧은 시간에 몰리는 트래픽에 효과적으로 대응
  • 요청별 타임스탬프를 모두 저장할 필요 없음
  • 이동 윈도 로그보다 메모리 사용량이 적음
  • 고정 윈도의 경계 문제 완화

11.5 단점

  • 직전 윈도의 요청이 균등하게 분포했다고 가정
  • 실제 요청 분포와 계산된 추정치 사이에 오차 발생 가능
  • 실험 결과에서는 이러한 오차가 심각한 문제로 나타나지 않음

12. 처리율 제한 데이터 저장소

12.1 데이터베이스 사용의 한계

  • 처리율 제한 여부를 확인하기 위한 카운터 필요
  • 모든 요청마다 카운터 조회 및 갱신 필요
  • 디스크 기반 데이터베이스 사용 시 지연 시간 증가 가능
  • 높은 요청량에서 데이터베이스 부하 증가 가능

12.2 인메모리 캐시 활용

  • 일반적으로 Redis와 같은 인메모리 저장소 활용
  • 빠른 읽기 및 쓰기 가능
  • 만료 시간 설정 가능
  • 카운터와 타임스탬프 자료구조 지원
  • 여러 처리율 제한 장치가 데이터를 공유하기 쉬움

13. 처리율 제한 규칙 관리

13.1 제한 규칙의 구성

  • 각 서비스의 요구사항에 따라 규칙 설정

  • 규칙에 포함될 수 있는 항목

    • 제한 대상
    • 요청 허용량
    • 시간 윈도 크기
    • API 경로
    • 사용자 등급
    • 초과 요청 처리 방식

13.2 규칙 저장

  • 규칙을 설정 파일 형태로 디스크에 저장 가능
  • 처리율 제한 장치가 설정 파일을 주기적으로 읽어 규칙 갱신 가능

14. 한도 초과 요청 처리

14.1 HTTP 상태 코드

  • 처리율 제한을 초과한 요청에 HTTP 429 Too Many Requests 응답 반환
  • 클라이언트에게 요청 한도 초과 사실 전달

14.2 응답 헤더

  • 클라이언트가 처리율 제한 상태를 확인할 수 있도록 응답 헤더 제공 가능

  • 전달 가능한 정보

    • 윈도당 허용되는 전체 요청 수
    • 현재 윈도에 남아 있는 요청 수
    • 다음 요청을 시도할 수 있는 시점
    • 재시도까지 기다려야 하는 시간

14.3 초과 요청의 보관

  • 제한된 요청을 즉시 폐기하지 않고 메시지 큐에 저장 가능
  • 나중에 비동기 방식으로 처리 가능
  • 모든 API 요청에 적용되는 방식은 아님
  • 주문, 작업 실행 등 비동기 처리가 가능한 요청에 적합

15. 분산 환경에서의 처리율 제한

15.1 주요 문제

  • 여러 처리율 제한 장치가 동시에 같은 카운터를 갱신하는 문제 발생

  • 대표적인 문제

    • 경쟁 조건
    • 서버 간 상태 동기화

16. 경쟁 조건

16.1 경쟁 조건의 발생 과정

  1. 현재 카운터 값 조회
  2. 한도 초과 여부 확인
  3. 카운터 값 증가
  • 여러 요청이 위 과정을 동시에 수행할 경우 동일한 카운터 값을 읽을 수 있음
  • 실제 요청 수보다 카운터가 적게 증가하는 문제 발생 가능
  • 허용 한도를 초과한 요청이 통과할 수 있음

16.2 락 사용

  • 공유 데이터에 락을 적용하여 한 번에 하나의 요청만 수정하도록 제한 가능
  • 경쟁 조건 방지 가능
  • 높은 동시성 환경에서는 대기 시간과 성능 저하 발생 가능

16.3 Lua 스크립트와 Redis 정렬 집합

  • 앞서 설명한 설계에서는 경쟁 조건의 해결책으로 Lua 스크립트와 Redis의 정렬 집합 활용 가능

Lua 스크립트

  • 조회, 비교, 증가 작업을 하나의 Lua 스크립트에 포함
  • 여러 Redis 명령을 하나의 작업처럼 실행
  • Redis 서버 내부에서 실행
  • 조회·판단·갱신 과정의 원자적 실행 가능

Lua 언어

  • 작고 가벼운 프로그래밍 언어
  • 다른 프로그램 내부에 삽입하여 사용하기 적합
  • Redis 내부에서 데이터 처리 로직을 실행할 때 활용 가능

Redis 정렬 집합

  • 각 데이터에 점수를 붙여 점수 순서대로 자동 정렬하는 자료구조
  • 처리율 제한에서는 요청 시간을 점수로 저장
  • 특정 시간 범위에 포함되는 요청만 조회 가능
  • 최근 요청 수를 정확하게 계산하는 데 활용 가능

17. 서버 간 상태 동기화

17.1 문제 상황

  • 처리율 제한 장치 서버를 여러 대 운영할 경우 서버마다 서로 다른 카운터를 가질 수 있음
  • 같은 클라이언트의 요청이 여러 서버로 분산되면 전체 요청량을 정확하게 계산하기 어려움

17.2 고정 세션 활용

  • 같은 클라이언트의 요청을 항상 같은 처리율 제한 장치로 전달
  • 서버별 로컬 카운터 사용 가능

한계

  • 특정 서버에 요청이 집중될 수 있음
  • 서버 장애 시 상태 이전이 어려움
  • 확장성과 유연성이 낮음
  • 처리율 제한만을 위해 고정 세션을 사용하는 것은 권장하기 어려움

17.3 중앙 집중형 데이터 저장소 활용

  • Redis와 같은 중앙 집중형 데이터 저장소 사용
  • 여러 처리율 제한 장치가 동일한 카운터 공유
  • 요청이 어느 서버에 도착하더라도 같은 제한 상태 확인 가능
  • 분산 환경에서 비교적 일관된 처리율 제한 제공 가능

18. 성능 및 분산 환경 고려 사항

18.1 여러 데이터센터 지원

  • 사용자와 가까운 데이터센터에서 요청 처리
  • 네트워크 지연 시간 감소
  • 지역별 처리율 제한 장치 배치 가능
  • 특정 데이터센터에 요청이 집중되는 문제 완화 가능

18.2 최종 일관성 모델 활용

  • 데이터센터 사이의 처리율 제한 상태를 비동기적으로 동기화
  • 모든 데이터센터의 상태를 즉시 동일하게 맞추지 않아도 됨
  • 데이터 동기화로 인한 지연 시간과 통신 비용 감소 가능
  • 데이터센터 사이의 상태가 일시적으로 다를 수 있음
  • 동기화가 완료되기 전까지 전체 처리율 한도를 순간적으로 초과할 가능성 존재
  • 정확한 전역 제한보다 낮은 지연 시간과 높은 가용성이 중요한 환경에 적합

19. 모니터링

19.1 모니터링 목적

  • 처리율 제한 장치가 효과적으로 동작하는지 확인
  • 설정한 알고리즘이 예상대로 동작하는지 확인
  • 처리율 제한 규칙이 지나치게 엄격하거나 느슨하지 않은지 확인

19.2 주요 모니터링 항목

  • 전체 요청 수
  • 허용된 요청 수
  • 거부된 요청 수
  • HTTP 429 응답 비율
  • 사용자 또는 API별 제한 발생 횟수
  • 처리율 제한 검사 지연 시간
  • Redis 조회 및 갱신 지연 시간
  • 규칙별 한도 사용률

19.3 모니터링 결과의 활용

  • 지나치게 많은 정상 요청이 거부되는 경우 제한 규칙 완화
  • 서버 과부하가 계속 발생하는 경우 제한 강화
  • 예상하지 못한 트래픽 패턴 발견
  • 알고리즘 또는 주요 인자 조정

20. 경성 처리율 제한과 연성 처리율 제한

20.1 경성 처리율 제한

  • 설정된 처리율 한도를 초과하는 요청을 허용하지 않는 방식
  • 한도에 도달하면 이후 요청을 즉시 거부
  • 엄격한 자원 보호가 필요한 경우에 적합
  • 순간적인 트래픽 증가를 허용하기 어려움

20.2 연성 처리율 제한

  • 설정된 한도를 일시적으로 초과하는 요청을 일정 범위까지 허용하는 방식
  • 짧은 시간 동안 발생한 버스트 트래픽 수용 가능
  • 사용자 요청을 유연하게 처리할 수 있음
  • 허용 범위를 지나치게 크게 설정하면 서버 과부하 발생 가능
profile
Live a life you will remember

0개의 댓글