학습 목표

상황

티켓 예매 서비스가 Application Load Balancer 뒤에서 Auto Scaling 그룹으로 운영됩니다. 평상시 인스턴스는 4대이고, 다음과 같이 설정되어 있습니다.

오픈 시각에 다음이 일어났습니다.

  1. 요청이 수십 배로 뛰었고 4대의 CPU가 곧바로 포화됐습니다.
  2. 지표가 집계되고 알람이 임계값 위반을 확정하기까지 시간이 걸렸습니다.
  3. 정책이 발동했지만 한 번에 1대만 추가했습니다.
  4. 새 인스턴스가 준비되기 전에 상태 확인이 실패해 일부가 비정상으로 판정되어 교체됐습니다.
  5. 쿨다운이 끝날 때까지 다음 추가가 지연됐습니다.
  6. 결국 필요한 대수에 도달했을 때는 피크가 지나간 뒤였습니다.
트래픽 급증에 스케일아웃이 늦는 구간 가로축은 시간이고 세로축은 요청량과 용량입니다. 축에는 값을 쓰지 않고 구간 이름만 씁니다. 평소에는 용량 선이 트래픽 선보다 위에 있어 여유가 있습니다. 어느 시점에 트래픽이 수직에 가깝게 급증하지만 용량 선은 한동안 그대로 있습니다. 그 사이가 용량이 부족한 구간이며 붉은 영역으로 표시했습니다. 부족 구간은 네 조각으로 쪼개집니다. 먼저 지표가 집계되어 CloudWatch 에 도착하는 지연이 있고, 그다음 알람이 정해진 평가 기간 동안 조건을 확인하는 시간이 있고, 그다음 Auto Scaling 이 인스턴스를 시작하는 시간이 있고, 마지막으로 인스턴스가 부팅과 배포를 마치고 상태 확인을 통과하는 초기화와 워밍업 시간이 있습니다. 이 네 조각이 모두 지난 뒤에야 용량 선이 올라가 트래픽을 수용합니다. 아래 두 상자는 이 구간을 줄이는 방법입니다. 예약 스케일링은 급증 시각을 미리 알 때 지표와 알람 구간을 통째로 없애고, 큐로 완충하면 처리 지연은 생기더라도 요청이 유실되지 않으므로 부족 구간의 피해 자체를 흡수합니다. 트래픽은 즉시 오르고 용량은 네 구간을 지나야 오릅니다 요청량 · 용량 용량이 부족한 구간 요청이 대기하거나 실패합니다 트래픽 용량 지표 집계 알람 평가 인스턴스 시작 초기화 · 워밍업 트래픽 수용 예약 스케일링 급증 시각을 미리 알고 있을 때 씁니다 지표 집계와 알람 평가 구간을 없앱니다 큐로 완충 (Amazon SQS) 요청을 큐에 받아 두고 뒤에서 처리합니다 지연은 생겨도 유실은 없습니다 Auto Scaling 을 켜 두었다는 것과 급증에 대비되었다는 것은 다른 말입니다
트래픽 급증 곡선 위에 지표 집계 지연, 알람 평가, 인스턴스 시작, 초기화 구간을 겹쳐 용량이 부족한 구간을 드러낸 타임라인 — 예약 스케일링과 큐 완충이 그 구간을 각각 어떻게 줄이는지 함께 표시합니다

지연 구간을 나눈다

스케일아웃이 완료되기까지의 구간과 각각을 줄이는 수단
구간 무슨 일이 일어나는가 줄이는 수단
1. 지표 집계 부하 변화가 지표에 반영되기까지 시간이 걸린다 세부 모니터링 사용, 반응이 빠른 지표 선택
2. 알람 평가 임계값 위반이 확정되어야 정책이 발동한다 평가 기간 조정, 대상 추적 정책 사용
3. 용량 계산 몇 대를 늘릴지 결정한다 단계 조정으로 위반 크기에 비례해 늘린다
4. 인스턴스 시작 인스턴스가 시작되고 부팅한다 가벼운 AMI, 예열 풀(warm pool)
5. 애플리케이션 초기화 런타임 기동, 의존성 연결, 캐시 예열 이미지에 미리 굽기, 워밍업 값 정확히 설정
6. 트래픽 수용 상태 확인 통과 후 대상 그룹에 들어간다 상태 확인 간격과 임계 횟수 조정

이 케이스에서 가장 큰 구간은 3(한 번에 1대)과 5(초기화 시간을 워밍업에 반영하지 않음)입니다. 그리고 급증 시각이 정해져 있다는 사실이, 반응을 빠르게 하는 것보다 더 좋은 답을 가능하게 합니다.

요구사항과 제약

요구사항과 제약
구분 내용 설계에 주는 함의
요구 1 오픈 시각의 오류율을 0에 가깝게 만든다 사후 반응만으로는 부족하다. 사전 확보가 필요하다
요구 2 예측하지 못한 급증에도 과부하로 무너지지 않아야 한다 초과 요청을 흡수하거나 버리는 정책이 필요하다
요구 3 평상시에는 여유 자원을 놀리지 않는다 상시 대용량 확보는 답이 아니다
제약 1 결제 요청은 유실되면 안 된다 버리는 대신 큐에 넣어 나중에 처리한다
제약 2 좌석 조회 응답은 즉시여야 한다 이 경로는 비동기로 바꿀 수 없다
제약 3 애플리케이션 초기화 시간을 당장 줄이기는 어렵다 초기화 시간을 설정에 정확히 반영해야 한다

배경 개념은 7장 로드 밸런싱과 오토스케일링과 12장 서버리스와 애플리케이션 통합에 있습니다.

후보 설계안 비교

후보 설계안 4종 비교 — 어느 지연 구간을 줄이는가
항목 A · 최소 용량을 피크에 맞춰 상시 유지 B · 대상 추적 정책으로 교체 C · B + 예약 스케일링 D · C + 큐로 쓰기 경로 완충
줄이는 구간 전부(반응 자체가 불필요) 2·3 2·3 + 예측된 급증은 4·5까지 남는 부족 구간을 견딘다
예측 가능한 급증 대응됨 여전히 늦다 사전에 용량이 서 있다 동일
예측 못 한 급증 대응됨 부분적 부분적 유입과 처리를 분리해 견딘다
평상시 자원 계속 놀린다 — 요구 3 위반 부하에 맞춰 조절 조절 + 시간대 조정 동일
요청 유실 없음 피크에 발생 줄어들지만 남는다 큐에 적재되어 유실되지 않는다
애플리케이션 변경 없음 없음 없음 쓰기 경로를 비동기로 바꾼다
판정 오답 — 비용 한정어와 충돌 필요하지만 불충분 채택 채택 — 제약 1을 만족

선택과 근거

D안을 고릅니다. 예측 가능한 급증은 예약 스케일링으로 미리 세우고, 예측하지 못한 급증은 대상 추적 정책으로 따라가며, 그래도 남는 부족 구간은 큐로 견딥니다. 세 수단이 서로 다른 문제를 담당합니다.

스케일링 정책 4종

Auto Scaling 정책 유형과 선택 기준
정책 유형 동작 언제 고르는가
TargetTrackingScaling 지표를 목표값에 유지하도록 용량을 조절한다 기본 선택. 임계값을 하나만 정하면 되고 축소도 함께 처리된다
StepScaling 위반 크기에 따라 단계별로 다른 양을 조정한다 급증 폭이 클 때 한 번에 여러 대를 늘려야 하는 경우
SimpleScaling (기본값) 한 번 조정하고 쿨다운이 끝날 때까지 기다린다 새로 설계할 때 고를 이유가 거의 없다
PredictiveScaling 과거 패턴을 학습해 미리 용량을 확보한다 주기적인 패턴이 있고 이력이 쌓였을 때. 대상 추적과 함께 쓴다

이 케이스의 원래 설정이 SimpleScaling이었다는 점이 문제의 절반입니다. 한 번 조정한 뒤 쿨다운을 기다리므로 급증을 따라갈 수 없습니다.

target-tracking.sh — 대상당 요청 수를 목표로 하는 대상 추적 정책 (이름과 목표값은 예시입니다)
aws autoscaling put-scaling-policy \
  --auto-scaling-group-name ticket-web \
  --policy-name track-requests-per-target \
  --policy-type TargetTrackingScaling \
  --target-tracking-configuration '{
      "TargetValue": 800.0,
      "PredefinedMetricSpecification": {
        "PredefinedMetricType": "ALBRequestCountPerTarget",
        "ResourceLabel": "app/ticket-alb/0123456789abcdef/targetgroup/ticket-tg/0123456789abcdef"
      }
    }'

워밍업과 쿨다운

새 인스턴스가 아직 준비되지 않았는데 지표에 포함되면 평균이 왜곡되어 필요 이상으로 인스턴스를 늘리거나, 준비 중인 인스턴스가 비정상으로 판정되어 교체됩니다. 이 케이스에서 4번 증상이 정확히 그것입니다.

워밍업과 쿨다운의 역할 구분
설정 무엇을 막는가 값을 정하는 근거
기본 인스턴스 워밍업 준비 중인 인스턴스가 지표에 포함되어 과잉 확장이 일어나는 것 실제 초기화 완료까지의 시간을 측정해 넣는다
상태 확인 유예 기간 준비 중인 인스턴스가 비정상으로 판정되어 교체되는 것 워밍업보다 넉넉하게
쿨다운 연속된 조정이 겹쳐 널뛰는 것 단순 조정 정책에서만 중요하다. 대상 추적에서는 워밍업이 그 역할을 한다
set-warmup.sh — 그룹 기본 워밍업과 상태 확인 유예 기간 설정 (초 단위 값은 측정 결과에 맞춰 정합니다)
aws autoscaling update-auto-scaling-group \
  --auto-scaling-group-name ticket-web \
  --default-instance-warmup 300 \
  --health-check-type ELB \
  --health-check-grace-period 420

예약 스케일링 — 정해진 시각에는 미리 세운다

오픈 시각이 정해져 있다면 반응을 빠르게 만들 이유가 없습니다. 미리 세워 두면 반응이 필요 없습니다. 예약 스케일링은 최소·최대·희망 용량을 시각에 맞춰 바꿉니다.

scheduled-scaling.sh — 오픈 30분 전 확장, 2시간 뒤 축소 (요일·시각·용량은 이 케이스의 예시입니다)
# 화요일 오전 4시 30분(UTC)에 미리 용량을 올립니다.
aws autoscaling put-scheduled-update-group-action \
  --auto-scaling-group-name ticket-web \
  --scheduled-action-name pre-open-scale-out \
  --recurrence "30 4 * * 2" \
  --min-size 20 \
  --desired-capacity 20

# 피크가 지난 뒤 원래 수준으로 되돌립니다.
aws autoscaling put-scheduled-update-group-action \
  --auto-scaling-group-name ticket-web \
  --scheduled-action-name post-open-scale-in \
  --recurrence "0 7 * * 2" \
  --min-size 4 \
  --desired-capacity 4

예열 풀 — 시작과 초기화 구간을 미리 끝내 둔다

초기화 시간을 당장 줄일 수 없다면(제약 3), 인스턴스를 미리 시작해 초기화까지 끝낸 뒤 중지 상태로 대기시킬 수 있습니다. 확장이 필요할 때 이 인스턴스를 깨우면 부팅과 초기화 구간이 사라집니다.

warm-pool.sh — 예열 풀 구성 (크기는 피크 증분에 맞춰 정합니다)
aws autoscaling put-warm-pool \
  --auto-scaling-group-name ticket-web \
  --min-size 10 \
  --pool-state Stopped

중지 상태로 두면 인스턴스 사용 요금은 발생하지 않지만 볼륨 요금은 계속됩니다. 예열 풀의 크기를 정할 때는 이 점을 고려합니다.

큐로 유입과 처리를 분리한다

제약 1(결제 요청 유실 불가)과 요구 2(예측 못 한 급증)를 함께 만족시키는 것은 완충 계층입니다. 웹 계층은 요청을 검증하고 큐에 넣은 뒤 즉시 응답하고, 처리 계층이 자기 속도로 큐를 소비합니다.

웹 인스턴스가 결제 처리를 동기로 수행합니다. 처리 속도가 유입 속도보다 느리면 요청이 대기하다가 타임아웃으로 실패하고, 사용자는 결제가 됐는지 알 수 없습니다. 부하가 그대로 데이터베이스까지 전달됩니다.

웹 인스턴스는 요청을 큐에 넣고 접수 번호를 즉시 돌려줍니다. 처리 계층은 큐 적체량을 기준으로 확장하며, 확장이 늦어도 요청은 큐에 남아 있으므로 유실되지 않습니다. 데이터베이스는 처리 계층의 속도만큼만 부하를 받습니다.

큐 완충을 도입할 때 정해야 하는 것
항목 결정 근거
큐 유형 순서와 중복 제거가 필요하면 FIFO, 아니면 표준 표준 큐는 처리량이 훨씬 크고, FIFO는 메시지 그룹 안에서 순서를 보장한다
확장 지표 큐의 대기 메시지 수를 인스턴스 수로 나눈 값 CPU보다 적체를 직접 반영한다
가시성 제한 시간 한 건 처리에 걸리는 최대 시간보다 길게 짧으면 처리 중인 메시지가 다시 전달되어 중복 처리된다
배달 못한 편지 큐(DLQ) 최대 수신 횟수를 정하고 별도 큐로 보낸다 독이 든 메시지가 큐를 막는 것을 방지한다
사용자 경험 접수 확인과 완료 알림을 나눈다 비동기 처리는 화면 흐름 변경을 동반한다

큐 유형과 속성의 세부 사항은 12장 서버리스와 애플리케이션 통합에서 다루고, 직접 만들어 보려면 실습 7 · SQS + Lambda 비동기 처리를 따라 합니다.

비용과 운영에 미치는 영향

처방별 비용·운영 항목의 변화
처방 비용 항목 운영 항목
대상 추적 정책 변화 없음 — 오히려 축소가 정확해져 절감된다 목표값을 부하 특성에 맞게 다시 정해야 한다
예약 스케일링 확장 구간만큼만 늘어난다 축소 액션을 짝으로 유지해야 한다. 일정 변경 시 함께 수정
예열 풀 중지 상태 인스턴스의 볼륨 요금이 계속된다 풀 크기와 AMI 갱신을 함께 관리
큐 완충 큐 요청 항목이 추가된다 DLQ 감시, 중복 처리에 대비한 멱등성 설계
피크 상시 확보(A안) 가장 크다 가장 단순하다

설계 체크리스트

스케일링 정책

시간 설정

완충과 보호

관련 시험 포인트

문제문의 신호와 정답 방향
문제문의 신호 고르는 것 소거하는 것
급증 시각이 정해져 있다 / 매주 같은 시간 예약 스케일링 임계값만 낮추는 안
예측 불가능한 급증 대상 추적 + 큐 완충 또는 서버리스 피크 용량 상시 확보
요청이 유실되면 안 된다 SQS로 완충 재시도만 늘리는 안
새 인스턴스가 계속 교체된다 상태 확인 유예 기간과 워밍업 확대 상태 확인을 끄는 안
인스턴스 기동이 너무 느리다 필요 요소를 AMI에 미리 굽거나 예열 풀 사용 더 큰 인스턴스로 바꾸는 안(기동 시간과 무관하다)
주기적 패턴이 뚜렷하고 이력이 충분하다 예측 스케일링을 대상 추적과 병행 단순 조정 정책
처리량이 0에서 급증까지 오간다 AWS Lambda 등 서버리스 최소 용량을 크게 잡는 안

이어서 볼 곳

공식 문서 출처