전체 응답 지연은 대략 ModelLatency + OverheadLatency다. 지연이 갑자기 늘면 ModelLatency(모델·인스턴스 부하 문제)인지 OverheadLatency(요청 처리·페이로드 문제)인지를 나눠 봐야 원인이 잡힌다.
같은 지표라도 "튀었을 때 무엇을 의심하고 무엇부터 손대는가"가 다르다.
지표
급증했을 때의 의미
1차 조치
ModelLatency
모델 연산이 오래 걸림 — 부하·모델 크기·배치 설정
인스턴스 타입 상향, 인스턴스 수 증설, 모델 경량화
OverheadLatency
요청 처리 부가 비용 — 큰 페이로드, 직렬화, 모델 로딩
페이로드 축소·압축, 요청 형식 단순화
Invocation4XXErrors
호출 측 잘못 — 형식·인증·크기 초과
클라이언트 페이로드 검증, 입력 스키마 점검
Invocation5XXErrors
서버 측 문제 — 컨테이너 충돌·타임아웃·자원 부족
컨테이너 로그 확인, 인스턴스 증설, 타임아웃 상향
CPUUtilization
연산 포화(멀티코어라 100%를 넘는 값으로 보고될 수 있음)
인스턴스 증설·타입 변경
MemoryUtilization
메모리 압박 — OOM으로 5XX와 함께 나타나기 쉬움
메모리 큰 타입으로 교체, 배치 크기 축소
Invocations
트래픽 변화 자체
Auto Scaling 타겟 재설정, 용량 계획
💡 관련 이론: 4XX와 5XX 오류는 책임 소재가 다르다. 4XX(클라이언트 오류)는 호출 측의 잘못된 입력·잘못된 형식·인증 문제로, 페이로드 검증이나 클라이언트 수정으로 해결한다. 5XX(서버 오류)는 모델 컨테이너 충돌·타임아웃·자원 부족 등 서버 측 문제다. 5XX가 급증하면 인스턴스 증설·헬스 체크·컨테이너 디버깅이 필요하다. 시험에서 "오류율 급증의 원인을 좁히려면"이라고 물으면 4XX/5XX 구분이 첫 단계다.
지표를 보기만 해서는 의미가 없다. 임계치를 넘으면 자동으로 알리거나 행동해야 한다. CloudWatch Alarm은 지표가 조건을 만족하면 상태를 ALARM으로 바꾸고 SNS 알림, Auto Scaling, Lambda 트리거 등을 실행한다.
import boto3cw = boto3.client("cloudwatch")cw.put_metric_alarm( AlarmName="HighModelLatency", Namespace="AWS/SageMaker", MetricName="ModelLatency", Dimensions=[{"Name": "EndpointName", "Value": "my-endpoint"}, {"Name": "VariantName", "Value": "AllTraffic"}], Statistic="Average", Period=60, # 60초 단위 평가 EvaluationPeriods=3, # 3번 연속 위반 시 ALARM Threshold=200000, # 200,000 마이크로초 = 200ms ComparisonOperator="GreaterThanThreshold", AlarmActions=["arn:aws:sns:us-east-1:123456789012:ops-alerts"], TreatMissingData="notBreaching", # 데이터 없음(트래픽 0)을 위반으로 보지 않음)
핵심 파라미터는 Period(평가 간격), EvaluationPeriods(몇 번 연속 위반해야 ALARM), Threshold(임계치), ComparisonOperator다. EvaluationPeriods를 늘리면 일시적 스파이크에 의한 오탐을 줄인다.
알람 파라미터
무엇을 조절하나
잘못 잡으면
Period
지표를 몇 초 단위로 묶어 평가
너무 짧으면 노이즈, 너무 길면 감지 지연
EvaluationPeriods
몇 주기 연속 위반해야 ALARM
1이면 스파이크마다 오탐
Statistic
Average / Sum / Maximum / p99 등
지연은 평균만 보면 꼬리 지연을 놓친다
TreatMissingData
데이터 없는 구간의 해석
트래픽 0인 야간에 헛알람이 뜰 수 있다
AlarmActions
울렸을 때 무엇을 할지
알림만 걸면 사람이 깰 때까지 방치된다
지연은 평균보다 꼬리(p90·p99)가 사용자 체감에 가깝다. 평균 80ms인데 p99가 3초라면 100명 중 1명은 사실상 실패로 느낀다. 평균 알람 하나만 걸어두고 "지연은 정상"이라고 판단하는 것이 운영에서 가장 흔한 착시다.
⚠️ 함정: 트래픽 급증으로 지연이 늘 때, "알람만 보내고 끝"이 아니라 Auto Scaling으로 인스턴스를 자동 증설하는 것이 정석이다. SageMaker 엔드포인트의 Auto Scaling은 보통 SageMakerVariantInvocationsPerInstance(인스턴스당 호출 수) 같은 지표를 타겟으로 정책을 건다. 시험에서 "트래픽 변동에 자동 대응"이면 단순 알람이 아니라 Application Auto Scaling 정책을 떠올려야 한다.
aas = boto3.client("application-autoscaling")# ① 스케일 대상 등록 — 배리언트의 인스턴스 수를 1~8 사이에서 조절aas.register_scalable_target( ServiceNamespace="sagemaker", ResourceId="endpoint/my-endpoint/variant/AllTraffic", ScalableDimension="sagemaker:variant:DesiredInstanceCount", MinCapacity=1, MaxCapacity=8,)# ② 타겟 추적 정책 — 인스턴스당 호출 수를 목표치 근처로 유지aas.put_scaling_policy( PolicyName="invocations-target-tracking", ServiceNamespace="sagemaker", ResourceId="endpoint/my-endpoint/variant/AllTraffic", ScalableDimension="sagemaker:variant:DesiredInstanceCount", PolicyType="TargetTrackingScaling", TargetTrackingScalingPolicyConfiguration={ "TargetValue": 1000.0, "PredefinedMetricSpecification": { "PredefinedMetricType": "SageMakerVariantInvocationsPerInstance"}, "ScaleInCooldown": 300, "ScaleOutCooldown": 60, },)
ScaleOut 쿨다운은 짧게, ScaleIn 쿨다운은 길게 — 늘릴 땐 빠르게, 줄일 땐 신중하게가 기본 감각이다.
인스턴스 추가에는 프로비저닝 시간이 걸린다. 스케일아웃이 즉발이 아니라는 점을 감안해 임계치를 여유 있게 잡는다.
엔드포인트가 다른 서비스(전처리 Lambda, 외부 API, 데이터베이스)와 엮이면, 어느 구간에서 지연이 나는지 한눈에 보기 어렵다. AWS X-Ray는 요청이 거쳐가는 각 구간(segment)의 소요 시간을 추적해 병목을 시각화한다. "전체 응답은 느린데 ModelLatency는 정상이다 → 앞단 Lambda나 네트워크가 병목"을 X-Ray 트레이스로 확인할 수 있다.
운영 모니터링은 "관측성(observability)의 세 기둥"으로 정리된다. 메트릭(무엇이 얼마나 — 지연·오류율·사용률), 로그(무슨 일이 — 이벤트·예외 상세), 트레이스(어디서 — 요청 흐름과 구간별 지연). CloudWatch Metrics·Logs와 X-Ray가 이 세 기둥에 정확히 대응한다. 문제 해결 순서도 보통 "메트릭으로 이상 감지 → 로그로 원인 상세 확인 → 트레이스로 어느 구간인지 특정"으로 흐른다.
운영 모니터링에는 비용도 포함된다. 항상 켜진 실시간 엔드포인트는 유휴 시간에도 비용이 나가므로, Invocations가 장기간 0에 가깝다면 서버리스나 비동기로 전환을 검토한다. CloudWatch 대시보드로 지연·오류·사용률·호출량을 한 화면에 모아 운영 상태를 한눈에 본다.