가상 면접 사례로 배우는 대규모 시스템 설계 기초 | 알렉스 쉬 - 교보문고

가상 면접 사례로 배우는 대규모 시스템 설계 기초 | 페이스북의 뉴스 피드나 메신저,유튜브, 구글 드라이브 같은 대규모 시스템은 어떻게 설계할까? IT 경력자라도 느닷없이 대규모 시스템을 설

product.kyobobook.co.kr


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

  • 처리율 제한 장치 (Rate Limiter)
    • 네트워크 시스템에서 클라이언트 또는 서비스가 보내는 트래픽의 처리율(Rate)을 제어하기 위한 장치
    • HTTP로 예를 들면 특정 기간 내에 전송되는 클라이언트의 요청 횟수를 제한
    • API 요청 횟수가 제한 장치에 정의된 임계치(Threshold)를 넘어서면 추가로 도달한 모든 호출은 처리가 중단(Block)
    • 적용 사례
      • 사용자는 초당 2회 이상 새 글을 올릴 수 없다.
      • 같은 IP 주소로는 하루에 10개 이상의 계정을 생성할 수 없다.
      • 같은 디바이스로는 주당 5회 이상 리워드(Reward)를 요청할 수 없다.

  • 처리율 제한 장치의 장점
    • Dos (Denial of Service) 공격에 의한 자원 고갈 (Resource Stravation)을 방지
      • 대형 IT 기업들이 공개한 거의 대부분의 API는 어떤 형태로든 처리율 제한 장치를 가지고 있다.
        • 예를 들어 트위터는 3시간 동안 300개의 트윗만 올릴 수 있도록 제한
        • 구글 독스 API는 사용자당 분당 300회의 Read 요청만 허용
        • 처리율 제한 장치는 추가 요청자에 대해서는 처리를 중단함으로써 Dos 공격을 방지
    • 비용 절감
      • 추가 요청에 대한 처리를 제한한다면 서버를 많이 두지 않아도 됨
      • 우선순위가 높은 API에 더 많은 자원을 할당할 수 있음
      • 처리율 제한은 제3자 API에 사용료를 지불하고 있는 회사들에게 매우 중요
        • 신용을 확인하거나, 신용카드 결제를 하거나, 건강 상태를 확인하거나 하기 위해 호출하는 API에 대한 과금이 횟수에 따라 이루어진다면, 그 횟수를 제한할 수 있어야 비용을 절감할 수 있을 것
    • 서버 과부하 방지
      • 봇(bot)에서 오는 트래픽
      • 사용자의 잘못된 이용 패턴

  • 처리율 제한 장치는 어디에 둘 것인가?
    • 클라이언트 측 (Client Side)
      • 일반적으로 클라이언트는 처리율 제한을 안정적으로 걸 수 있는 장소가 아니다.
      • 클라이언트 요청은 쉽게 위변조가 가능함
      • 모든 클라이언트의 구현을 통제하는 것도 어려움
    • 서버 측 (Server Side)
    • 미들 웨어 (Middleware)
      • 처리율 제한 장치를 API 서버에 두는 대신, 처리율 제한 미들웨어를 만들어 통제
      • HTTP 상태코드 429 (Too many requests)를 반환
    • 클라우드 마이크로서비스의 경우
      • 처리율 제한 장치는 보통 API 게이트웨이라 불리는 컴포너트에 구현
      • API 게이트웨이는 처리율 제한, SSL 종단 (Termination), 사용자 인증 (Authentication), IP 허용 (Whitelist) 관리 등을 지원하는 완전 위탁관리형 서비스 (Fully Managed), 즉 클라우드 업체가 유지 보수를 담당하는 서비스
      • 하지만 일단 API 게이트웨이가 처리율 제한을 지원하는 미들웨어라는 점만 기억하자.
    • 정답은 없다. 회사의 기술 스택이나 엔지니어링 인력, 우선 순위, 목표에 따라 달라질 수 있다.
      • 프로그래밍 언어, 캐시 서비스 등 현재 사용하고 있는 기술 스택을 점검하라
        • 현재 사용하는 프로그래밍 언어가 서버 측 구현을 지원하기 충분한 효율을 가졌는지 확인하라.
      • 사업 필요에 맞는 처리율 제한 알고리즘을 찾아라.
        • 서버 측에서 모든 것을 구현하기로 했다면 알고리즘은 자유롭게 선택할 수 있다.
        • 하지만 제 3 사업자가 제공하는 게이트웨이를 사용하기로 했다면 선택지는 제한된다.
  • 처리율 제한 장치를 구현하는 데에는 비용이 많이 든다. 충분한 인력이 없다면 상용 API 게이트웨이를 쓰는 것이 바람직한 방법일 것이다.

  • 처리율 제한 알고리즘
    • 토큰 버킷 (Token Bucket)
      • 간단하고 이해도도 높고, 보편적으로 사용됨
        • API 엔드포인트마다 별도의 버킷을 두고 버킷의 용량을 넘어서는 요청을 제한하는 방법
        • 장점
          • 구현이 쉬움
          • 메모리 사용 측면에서도 효율적
          • 짧은 시간에 집중되는 트래픽도 처리 가능
          • 버킷에 남은 토큰이 있기만 하면 요청은 시스템에 전달
        • 단점
          • 버킷 크기와 토큰 공급률이라는 두 개 인자를 적절히 튜닝하는 것이 어려움

      • 누출 버킷 (Leaky Bucket)
        • 토큰 버킷 알고리즘과 유사하지만, 요청 처리율이 고정되어 있음
        • FIFO (First In First Out) 큐로 구현
        • 동작 원리
          • 요청이 도착하면 큐가 가득 차 있는지 확인
          • 빈 자리가 있는 경우 큐에 요청을 추가
          • 큐가 가득 차 있는 경우 새 요청은 버림
          • 지정된 시간마다 큐에서 요청을 꺼내 처리
        • 장점
          • 큐의 크기가 제한되어 있어 메모리 사용량 측면 효율적
          • 고정 처리율을 가지고 있어 안정적 출력이 필요한 경우 적합
        • 단점
          • 단시간에 많은 트래픽이 몰리는 경우 큐에 오래된 요청들이 쌓이게 됨
          • 오래된 요청들을 제 때 처리하지 못하면 최신 요청들이 버려지게 됨
          • 두 개 인자를 가조 있는데, 인자 튜닝이 까다로움

      • 고정 윈도 카운터 (Fixed Window Counter)
        • 타임라인을 고정된 간격의 윈도우로 나누어 윈도우마다 카운터를 붙이는 방식
        • 요청이 접수될 때 마다 카운터의 값이 1씩 증가
        • 카운터의 값이 사전에 설정된 임계치에 도달하면 새로운 요청은 새 윈도가 열릴 때 까지 버려짐
        • 장점
          • 높은 메모리 효율
          • 러닝 커브 낮음
          • 윈도가 닫히는 시점에 카운터를 초기화하는 방식은 특정 트래픽 패턴을 처리하기 적합
        • 단점
          • 윈도 경계 부근에서 일시적으로 많은 트래픽이 몰려드는 경우 기대했던 시스템 처리 한도보다 많은 양의 요청을 처리해야 함

      • 이동 윈도 로그 (Sliding Window Log)
        • 고정 윈도 카운터 알고리즘의 문제점 (경계 부근에 트래픽이 몰릴 경우 과다 요청 처리)을 해결하기 위한 알고리즘
        • 요청의 타임스탬프를 추적, 새 요청이 오면 만료된 타임스탬프를 제거하고, 새 요청의 타임스탬프를 로그에 추가한다.
        • 로그의 크기가 허용치보다 같거나 작으면 요청을 시스템에 전달하고, 그렇지 않은 경우에는 처리를 거부한다.
        • 장점
          • 아주 정교한 처리율 제한 메커니즘
          • 허용되는 요청의 개수는 시스템 처리율 한도를 넘지 않는다.
        • 단점
          • 다량의 메모리를 사용 (거부된 요청의 타임스탬프도 보관하기 때문)

      • 이동 윈도 카운터 (Sliding Window Counter)
        • 고정 윈도 카운터 + 이동 윈도 로그 알고리즘 결합
        • 장점
          • 이전 시간대의 평균 처리율에 따라 현재 윈도 상태를 계산 → 짧은 시간에 몰리는 트래픽에 잘 대응
          • 메모리 효율 좋음
        • 단점
          • 직전 시간대에 도착한 요청이 균등하게 분포되어 있다고 가정한 상태에서 추정치를 계산하기에 다소 느슨함 (치명적인 단점은 아님, CloudFlare 실험 결과 0.003%의 오차범위)

      • 정리
        • 이번 장에서는 처리율 제한을 구현하는 여러 알고리즘과, 그 장단점을 살펴보았다.
        • 알고리즘 이외에도 해당 알고리즘을 구현하는 아키텍처, 분산환경에서의 처리율 제한 장치, 성능 최적화와 모니터링 등의 주제를 살펴보았다.
        • 시간이 허락된다면 다음과 같은 방법도 고려해볼만 하다
          • 경성 (Hard) 또는 연성 (Soft) 처리율 제한
            • 경성 처리율 제한 : 요청의 개수는 임계치를 절대 넘어설 수 없다.
            • 연성 처리율 제한 : 요청 개수는 잠시 동안은 임계치를 넘어설 수 있다
          • 다양한 계층에서의 처리율 제한
            • 이번 장에서는 애플리케이션 계층에서의 처리율 제한에 대해서만 살펴보았다.
            • OSI 7계층 중 네트워크 계층
              • Iptables를 사용하여 IP 주소에 처리율 제한을 적용할 수 잇다.
          • 처리율 제한 회피
            • 클라이언트 측 캐시를 사용하여 API 호출 횟수를 줄인다.
            • 처리율 제한의 임계치를 이해하고, 짧은 시간 동안 너무 많은 메시지를 보내지 않도록 한다.
            • 예외나 에러를 처리하는 코드를 도입하여 클라이언트가 예외적 상황으로부터 우아하게 복구될 수 있도록 한다.
            • 재시도 로직을 구현할 때는 충분한 백오프 시간을 둔다.

      느낀 점
      • 처리율 제한이 없다면 DDos 공격이나 무차별적인 공격 기법에 저항할 수 없겠다고 생각했다.
      • 꼭 악의적 공격이 아니더라도, 사용자가 짧은 시간에 수많은 새로고침을 진행하거나 (선착순 예약 시스템, 수강 신청 등), 네트워크 오류로 인해 다량의 요청이 주어졌을 경우 등등 다양한 경우를 고려했을 때 처리율 제한은 선택이 아닌 필수적인 요소인 것 같다.
      • 결국 네트워크 트래픽을 원만하게 조절하여 서비스 성능을 개선할 수 있고, 고의든 실수든 무의미한 대량의 트래픽을 방어하여 예산적으로도 방어할 수 있다는건 큰 장점이다.
      • 분산 환경에서 처리율 제한을 위해 사용자의 고정 세션(Sticky Session)을 활용하기보다 Redis와 같은 중앙 집중형 캐시 데이터 저장소를 사용한다는 점을 주의깊게 보았다.
      • 최근 Redis에 대해 많은 관심과 공부를 하고 있다. 다양한 분야에서 Redis가 어떻게 쓰이는지 조금 더 세밀하게 알아볼 수 있는 기회여서 좋았다.

+ Recent posts