아키텍처 케이스 · 7
트래픽 급증에 스케일아웃이 못 따라갔다
Auto Scaling은 설정되어 있었고 정책도 있었습니다. 그런데도 10분 동안 오류를 냈습니다. 원인은 정책의 유무가 아니라 반응이 완료되기까지의 지연 구간입니다. 지표를 모으고, 알람을 평가하고, 인스턴스를 시작하고, 초기화가 끝나기까지의 시간이 급증 속도보다 느리면 부족 구간이 생깁니다.
학습 목표
- 스케일아웃 반응이 완료되기까지의 지연 구간을 단계별로 분해할 수 있습니다.
- 대상 추적 · 단계 조정 · 단순 · 예측 스케일링 정책의 성격을 구분해 고를 수 있습니다.
- 워밍업과 쿨다운이 어떤 오작동을 막는지 설명할 수 있습니다.
- 예측 가능한 급증에 예약 스케일링을 적용하는 판단을 할 수 있습니다.
- 큐로 요청을 완충해 처리 속도와 유입 속도를 분리하는 설계를 설명할 수 있습니다.
상황
티켓 예매 서비스가 Application Load Balancer 뒤에서 Auto Scaling 그룹으로 운영됩니다. 평상시 인스턴스는 4대이고, 다음과 같이 설정되어 있습니다.
- 스케일링 정책은 평균 CPU 사용률 70% 기준의 단순 조정 정책 하나입니다. 한 번에 1대를 추가합니다.
- 인스턴스는 부팅 후 애플리케이션 초기화와 캐시 예열에 수 분이 걸립니다.
- 워밍업과 쿨다운 값은 기본 상태로 두었습니다.
- 공연 티켓 오픈 시각은 매주 화요일 오후 2시로 정해져 있습니다.
오픈 시각에 다음이 일어났습니다.
- 요청이 수십 배로 뛰었고 4대의 CPU가 곧바로 포화됐습니다.
- 지표가 집계되고 알람이 임계값 위반을 확정하기까지 시간이 걸렸습니다.
- 정책이 발동했지만 한 번에 1대만 추가했습니다.
- 새 인스턴스가 준비되기 전에 상태 확인이 실패해 일부가 비정상으로 판정되어 교체됐습니다.
- 쿨다운이 끝날 때까지 다음 추가가 지연됐습니다.
- 결국 필요한 대수에 도달했을 때는 피크가 지나간 뒤였습니다.
지연 구간을 나눈다
| 구간 | 무슨 일이 일어나는가 | 줄이는 수단 |
|---|---|---|
| 1. 지표 집계 | 부하 변화가 지표에 반영되기까지 시간이 걸린다 | 세부 모니터링 사용, 반응이 빠른 지표 선택 |
| 2. 알람 평가 | 임계값 위반이 확정되어야 정책이 발동한다 | 평가 기간 조정, 대상 추적 정책 사용 |
| 3. 용량 계산 | 몇 대를 늘릴지 결정한다 | 단계 조정으로 위반 크기에 비례해 늘린다 |
| 4. 인스턴스 시작 | 인스턴스가 시작되고 부팅한다 | 가벼운 AMI, 예열 풀(warm pool) |
| 5. 애플리케이션 초기화 | 런타임 기동, 의존성 연결, 캐시 예열 | 이미지에 미리 굽기, 워밍업 값 정확히 설정 |
| 6. 트래픽 수용 | 상태 확인 통과 후 대상 그룹에 들어간다 | 상태 확인 간격과 임계 횟수 조정 |
이 케이스에서 가장 큰 구간은 3(한 번에 1대)과 5(초기화 시간을 워밍업에 반영하지 않음)입니다. 그리고 급증 시각이 정해져 있다는 사실이, 반응을 빠르게 하는 것보다 더 좋은 답을 가능하게 합니다.
요구사항과 제약
| 구분 | 내용 | 설계에 주는 함의 |
|---|---|---|
| 요구 1 | 오픈 시각의 오류율을 0에 가깝게 만든다 | 사후 반응만으로는 부족하다. 사전 확보가 필요하다 |
| 요구 2 | 예측하지 못한 급증에도 과부하로 무너지지 않아야 한다 | 초과 요청을 흡수하거나 버리는 정책이 필요하다 |
| 요구 3 | 평상시에는 여유 자원을 놀리지 않는다 | 상시 대용량 확보는 답이 아니다 |
| 제약 1 | 결제 요청은 유실되면 안 된다 | 버리는 대신 큐에 넣어 나중에 처리한다 |
| 제약 2 | 좌석 조회 응답은 즉시여야 한다 | 이 경로는 비동기로 바꿀 수 없다 |
| 제약 3 | 애플리케이션 초기화 시간을 당장 줄이기는 어렵다 | 초기화 시간을 설정에 정확히 반영해야 한다 |
배경 개념은 7장 로드 밸런싱과 오토스케일링과 12장 서버리스와 애플리케이션 통합에 있습니다.
후보 설계안 비교
| 항목 | A · 최소 용량을 피크에 맞춰 상시 유지 | B · 대상 추적 정책으로 교체 | C · B + 예약 스케일링 | D · C + 큐로 쓰기 경로 완충 |
|---|---|---|---|---|
| 줄이는 구간 | 전부(반응 자체가 불필요) | 2·3 | 2·3 + 예측된 급증은 4·5까지 | 남는 부족 구간을 견딘다 |
| 예측 가능한 급증 | 대응됨 | 여전히 늦다 | 사전에 용량이 서 있다 | 동일 |
| 예측 못 한 급증 | 대응됨 | 부분적 | 부분적 | 유입과 처리를 분리해 견딘다 |
| 평상시 자원 | 계속 놀린다 — 요구 3 위반 | 부하에 맞춰 조절 | 조절 + 시간대 조정 | 동일 |
| 요청 유실 | 없음 | 피크에 발생 | 줄어들지만 남는다 | 큐에 적재되어 유실되지 않는다 |
| 애플리케이션 변경 | 없음 | 없음 | 없음 | 쓰기 경로를 비동기로 바꾼다 |
| 판정 | 오답 — 비용 한정어와 충돌 | 필요하지만 불충분 | 채택 | 채택 — 제약 1을 만족 |
선택과 근거
D안을 고릅니다. 예측 가능한 급증은 예약 스케일링으로 미리 세우고, 예측하지 못한 급증은 대상 추적 정책으로 따라가며, 그래도 남는 부족 구간은 큐로 견딥니다. 세 수단이 서로 다른 문제를 담당합니다.
스케일링 정책 4종
| 정책 유형 | 동작 | 언제 고르는가 |
|---|---|---|
TargetTrackingScaling |
지표를 목표값에 유지하도록 용량을 조절한다 | 기본 선택. 임계값을 하나만 정하면 되고 축소도 함께 처리된다 |
StepScaling |
위반 크기에 따라 단계별로 다른 양을 조정한다 | 급증 폭이 클 때 한 번에 여러 대를 늘려야 하는 경우 |
SimpleScaling (기본값) |
한 번 조정하고 쿨다운이 끝날 때까지 기다린다 | 새로 설계할 때 고를 이유가 거의 없다 |
PredictiveScaling |
과거 패턴을 학습해 미리 용량을 확보한다 | 주기적인 패턴이 있고 이력이 쌓였을 때. 대상 추적과 함께 쓴다 |
이 케이스의 원래 설정이 SimpleScaling이었다는 점이 문제의 절반입니다.
한 번 조정한 뒤 쿨다운을 기다리므로 급증을 따라갈 수 없습니다.
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번 증상이 정확히 그것입니다.
| 설정 | 무엇을 막는가 | 값을 정하는 근거 |
|---|---|---|
| 기본 인스턴스 워밍업 | 준비 중인 인스턴스가 지표에 포함되어 과잉 확장이 일어나는 것 | 실제 초기화 완료까지의 시간을 측정해 넣는다 |
| 상태 확인 유예 기간 | 준비 중인 인스턴스가 비정상으로 판정되어 교체되는 것 | 워밍업보다 넉넉하게 |
| 쿨다운 | 연속된 조정이 겹쳐 널뛰는 것 | 단순 조정 정책에서만 중요하다. 대상 추적에서는 워밍업이 그 역할을 한다 |
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
예약 스케일링 — 정해진 시각에는 미리 세운다
오픈 시각이 정해져 있다면 반응을 빠르게 만들 이유가 없습니다. 미리 세워 두면 반응이 필요 없습니다. 예약 스케일링은 최소·최대·희망 용량을 시각에 맞춰 바꿉니다.
# 화요일 오전 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), 인스턴스를 미리 시작해 초기화까지 끝낸 뒤 중지 상태로 대기시킬 수 있습니다. 확장이 필요할 때 이 인스턴스를 깨우면 부팅과 초기화 구간이 사라집니다.
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 등 서버리스 | 최소 용량을 크게 잡는 안 |
이어서 볼 곳
- 7장 · 로드 밸런싱과 오토스케일링 스케일링 정책 유형, 수명주기 훅, 워밍업과 쿨다운을 정면으로 다룹니다.
- 12장 · 서버리스와 애플리케이션 통합 SQS 표준과 FIFO, 가시성 제한 시간, DLQ, 이벤트 기반 결합을 다룹니다.
- 실습 2 · ALB + ASG 웹 티어 스케일링 정책을 붙이고 부하를 걸어 반응 시간을 직접 재 봅니다.
- 실습 7 · SQS + Lambda 비동기 처리 큐 완충과 DLQ, 가시성 제한 시간을 직접 구성하고 실패를 재현합니다.
- 케이스 5 · 단일 AZ 설계가 장애로 전면 중단됐다 같은 Auto Scaling 구성이 가용 영역 장애에서는 어떻게 실패하는지 비교합니다.
- 복원력 있는 아키텍처 설계 (26%) 확장 가능하고 느슨하게 결합된 아키텍처의 출제 포인트를 정리했습니다.
공식 문서 출처
- Amazon EC2 Auto Scaling API 레퍼런스 — PutScalingPolicy
— 정책 유형 4종(
TargetTrackingScaling·StepScaling·SimpleScaling(기본값) ·PredictiveScaling)과 워밍업 파라미터 - Amazon EC2 Auto Scaling API 레퍼런스 — PredefinedMetricSpecification — 대상 추적이 쓸 수 있는 사전 정의 지표 4종
- Amazon EC2 Auto Scaling API 레퍼런스 — UpdateAutoScalingGroup — 기본 인스턴스 워밍업과 상태 확인 유예 기간의 의미
- Amazon EC2 Auto Scaling API 레퍼런스 — PutScheduledUpdateGroupAction — 반복 일정과 시간대 지정, 최소·최대·희망 용량 변경
- Amazon EC2 Auto Scaling API 레퍼런스 — PutWarmPool — 예열 풀의 상태와 크기 설정
- Amazon SQS API 레퍼런스 — CreateQueue — 표준 큐가 기본이며 큐 유형을 나중에 바꿀 수 없다는 서술, 가시성 제한 시간 기본값
- Amazon EC2 API 레퍼런스 — StopInstances — 중지된 인스턴스에는 사용 요금이 부과되지 않지만 볼륨 요금은 계속된다는 서술