
실시간 AI 운영하기: SLA, 관측성(Observability), 그리고 장애 발생 시점 파악하기
요약
실시간 AI 시스템의 운영적 성숙도를 높이기 위한 SLA(서비스 수준 협약) 설정 방법을 다룹니다. 지연 시간, 가용성, 데이터 신선도, 재현율이라는 네 가지 핵심 차원을 통해 시스템의 성능과 정확성을 정의하는 가이드를 제공합니다.
핵심 포인트
- 지연 시간은 평균이 아닌 P99 또는 P999 기준으로 정의해야 함
- 가용성 목표에 따라 운영 복잡성이 크게 달라짐을 인지해야 함
- 데이터 신선도는 시스템의 정확성을 결정하는 중요한 차원임
- 벡터 검색 시스템에서는 재현율을 품질 계약의 일부로 포함해야 함
이 시리즈의 이전 네 포스트에서는 대규모 실시간 AI의 세 가지 아키텍처 기둥인 피처 파이프라인(feature pipelines), 피처 스토어(feature stores), 그리고 벡터 검색(vector search)을 다루었습니다. 각 포스트는 스택의 특정 레이어에 특화된 설계 결정과 장애 모드(failure modes)를 다루었습니다.
이 마지막 포스트는 이 모든 것 위에 위치한 레이어인 운영(operations)에 관한 것입니다.
기술적으로 견고한 파이프라인, 잘 구조화된 피처 스토어, 그리고 세심하게 관리되는 벡터 인덱스(vector index)를 설계할 수는 있습니다. 하지만 그럼에도 불구하고 프로덕션 환경에서 실행하기 어렵고, 장애로부터 복구하는 데 시간이 오래 걸리며, 실제로 제대로 작동하고 있는지 만성적으로 불분명한 시스템이 될 수 있습니다. 아키텍처적으로 견고한 시스템과 운영적으로 성숙한 시스템의 차이는, 설계된 시스템과 운영된 시스템의 차이입니다.
이 포스트는 실시간 AI 시스템의 운영적 성숙도가 어떤 모습인지에 대해 다룹니다. 즉, 무엇이 "작동한다"는 의미인지 정의하는 방법, 작동하지 않을 때 이를 아는 방법, 그리고 문제가 발생했을 때 복구하는 방법에 관한 것입니다.
SLA로 시작하기: 실제로 무엇을 약속하고 있는가?
운영에 관한 모든 논의는 서비스 수준 협약(SLA, service level agreement)에서 시작해야 합니다. 이는 단순한 준수 문서가 아니라, 명확성을 강제하는 기능(forcing function)으로서의 역할을 합니다.
실시간 AI 시스템을 위한 SLA는 다음 네 가지 질문에 답할 수 있어야 합니다:
1. 지연 시간(latency) 목표는 무엇인가?
단순한 평균 지연 시간이 아니라, P99를 기준으로 해야 합니다. 99번째 백분위수(99th percentile)는 사용자에게 눈에 보이는 성능 저하가 발생하는 지점입니다. "평균 지연 시간은 50ms입니다"라는 말은 "요청의 1%는 2초가 걸립니다"라는 말과 양립할 수 있으며, 이는 실시간 사용자 대면 시스템에서는 수용 불가능할 가능성이 높습니다. 지연 시간 목표를 P99로 정의하십시오. 꼬리 지연 시간(tail latency)이 특히 중요한 시스템의 경우 선택적으로 P999를 정의할 수도 있습니다.
2. 가용성(availability) 목표는 무엇인가?
어느 정도의 시간 범위 동안 요청의 어느 정도 비율이 성공해야 합니까? 99.9%의 가용성은 연간 허용 가능한 다운타임이 약 8.7시간임을 의미합니다. 99.99%는 52분을 의미합니다. 이 두 목표 사이의 운영 복잡성 차이는 상당합니다. 여러분이 어떤 목표를 위해 설계하고 있는지 파악하십시오.
3. 신선도(Freshness) 목표는 무엇인가?
실시간 AI의 경우, 이는 일반적인 SLA (Service Level Agreement) 프레임워크에서 종종 누락되는 차원입니다. 시스템이 저하되었다고 간주되기 전까지 피처(Feature)가 얼마나 오래되어도 괜찮습니까? 검색 품질에 영향을 미치기 전까지 벡터 인덱스(Vector index) 업데이트가 얼마나 오래되어도 괜찮습니까? 신선도는 단순한 성능(Performance) 차원이 아니라 정확성(Correctness) 차원입니다.
4. 재현율(Recall) 목표는 무엇인가?
벡터 검색(Vector search)을 사용하는 시스템에서 재현율은 품질 계약의 일부입니다. 기술적으로 가용(Available) 상태이고 지연 시간(Latency) 목표 내에 있더라도, 60%의 재현율로 검색 결과를 반환하는 시스템은 많은 유스케이스(Use case)에서 기능적으로 고장 난 상태입니다. 최소 허용 가능한 재현율 임계값을 정의하고, 이를 위반하는 경우 SLA 위반으로 취급하십시오.
지연 시간(Latency), 가용성(Availability), 신선도(Freshness), 재현율(Recall)이라는 이 네 가지 차원이 실시간 AI 시스템을 위한 완전한 SLA 표면(SLA surface)을 형성합니다. 대부분의 팀은 처음 두 가지를 정의하고 마지막 두 가지는 무시합니다. 마지막 두 가지가 바로 '조용한 성능 저하(Silent degradation)'가 숨어 있는 곳입니다.
지연 시간 예산(Latency Budget): 시간이 실제로 소비되는 곳
P99 지연 시간 목표를 설정했다면, 다음 단계는 지연 시간 예산(Latency budget)을 설정하는 것입니다. 이는 서빙 경로(Serving path)의 각 구성 요소에 해당 목표를 명시적으로 할당하는 것을 의미합니다.
전형적인 실시간 추론(Inference) 서빙 경로는 다음과 같습니다:
요청 수신 (Request received)
│
├── 피처 검색 (Feature retrieval, 온라인 스토어 조회)
...
지연 시간 예산이 없다면, 각 구성 요소는 암묵적으로
| 구성 요소 | 예산 | 비고 |
|---|---|---|
| 네트워크 (ingress + egress) | 10ms | 대체로 고정됨; 지리적 근접성을 최적화해야 함 |
| ... |
예산(Budget)은 트레이드오프(tradeoffs)를 가시화합니다. 만약 모델 추론 (model inference) 단계가 35ms 대신 60ms가 소요된다면, 이를 보완하기 위해 다른 어떤 구성 요소가 압축되어야 하는지, 혹은 전체 목표치를 재협상해야 하는지를 즉시 알 수 있습니다. 예산이 없다면, 60ms의 모델 추론 단계는 명확한 다음 조치 없이 그저 "모델이 느리다"라는 정보에 그치고 맙니다.
지연 시간 예산 (Latency budgets)은 모니터링 단계에서 강제되어야 합니다. 만약 피처 검색 (feature retrieval)이 정기적으로 할당된 범위를 초과한다면, 그것은 단순한 데이터 포인트가 아니라 하나의 경고 (alert)입니다.
관측성 (Observability): 전체 시그널 스택
실시간 AI 시스템을 위한 관측성 (Observability)은 스택의 모든 계층에서 시그널을 모니터링할 것을 요구합니다. 대부분의 인프라 모니터링은 컴퓨팅 (compute) 및 네트워크 (network) 계층을 잘 다룹니다. 하지만 AI 특화 계층인 피처 신선도 (feature freshness), 값 분포 (value distributions), 재현율 (recall) 등은 거의 항상 모니터링 도구(instrumentation)가 부족한 상태입니다.
전체 시그널 스택은 다음과 같습니다:
이러한 시그널 중 몇 가지는 성숙한 엔지니어링 조직에서조차 운영 모니터링에서 관례적으로 누락되기 때문에 특별한 주의를 기울일 가치가 있습니다.
추론 시점의 피처 결측률 (Feature null rate at inference time). 엔티티 (entity)가 새롭거나, 파이프라인 (pipeline)이 실패하거나, 스키마 (schema)가 변경되어 피처 값이 누락되는 경우, 대부분의 피처 스토어 (feature store)는 조용히 기본값 (default value)을 제공합니다. 결측률 (null rate)은 이러한 현상이 얼마나 자주 발생하는지를 알려줍니다. 결측률의 갑작스러운 급증은 파이프라인 실패, 스키마 드리프트 (schema drift), 또는 콜드 스타트 (cold start)로 인한 볼륨 변화를 나타내는 선행 지표입니다. 이를 추적하지 않는다면, 입력 품질의 중요한 차원에 대해 눈을 가리고 비행하는 것과 같습니다.
예측 분포 드리프트 (Prediction distribution drift). 모델 출력의 통계적 분포가 변화한다면 — 더 극단적인 점수, 다른 평균, 혹은 분산의 붕괴 등 — 상류(upstream)의 무언가가 변경된 것입니다. 이는 피처 파이프라인 (feature pipeline) 문제일 수도 있고, 데이터 품질 문제이거나, 혹은 기저 인구 집단 (underlying population)의 실제적인 변화일 수도 있습니다. 출력 분포를 모니터링하는 것이 정확히 무엇이 문제인지 알려주지는 않지만, 무언가 변했다는 사실을 알려주며, 이는 조사를 시작하게 만드는 신호가 됩니다.
시간 경과에 따른 훈련-서빙 왜곡 (Training-serving skew over time). 우리는 포스트 2와 3에서 훈련-서빙 왜곡을 아키텍처 문제로 다루었습니다. 여기서는 이를 운영 지표 (operational metric)로 다룹니다. 서빙 시점의 피처 값을 주기적으로 샘플링하고 그 분포를 훈련 시점의 값과 비교하면, 단일한 잘못된 배포가 아니라 소스 데이터, 변환 로직(transformation logic), 또는 서빙 동작의 느린 드리프트로 인해 점진적으로 축적되는 왜곡을 포착할 수 있습니다.
장애 모드 및 복구 패턴 (Failure Modes and Recovery Patterns)
파이프라인 장애 (Pipeline Failures)
배치 파이프라인 (Batch pipeline) 장애는 가장 단순합니다. 작업이 실패하면 스케줄러가 이를 보고하고, 온콜 엔지니어 (on-call engineer)가 이를 재실행할 수 있습니다. 문제는 그 사이에 피처 스토어 (feature store)가 우아하게 성능을 저하시키며(degrade gracefully) 버텨주는가 하는 점입니다.
'오래되었지만 사용 가능한(stale-but-available)' 설계. 파이프라인이 지연될 때 에러를 반환하는 피처 스토어보다는 오래된(stale) 값을 반환하는 피처 스토어가 더 낫습니다. 오래된 값은 품질이 다소 저하될 수는 있어도 모델을 계속 작동하게 유지합니다. 반면 에러는 모델의 작동을 완전히 중단시킵니다. 명시적인 데이터 신선도 임계값(staleness thresholds)을 구축하십시오. N분보다 오래된 값은 경고를 발생시키고, M분보다 오래된 값은 폴백(fallback) 동작을 트리거하도록 설정합니다.
스트리밍 파이프라인 (Streaming pipeline) 장애는 더 복잡합니다. 이벤트 큐(event queue)에 지연(lag)이 쌓이면서 처리가 뒤처지는 스트리밍 작업은 즉시 실패하지 않을 수도 있습니다. 계속 처리를 진행할 수는 있지만, 지연이 증가하면서 결과적으로 점점 더 오래된 피처를 조용히 전달하게 됩니다. **스트림 지연 모니터링 (Stream lag monitoring)**이 바로 그 신호입니다. 이벤트가 생성된 시점과 처리된 시점 사이의 간격을 추적하고, 이 간격이 임계값을 넘으면 경고를 보내십시오.
# 스트림 지연(Stream lag) 경고 — 개념적 예시
def check_stream_lag(consumer_group, max_lag_seconds):
lag = kafka_consumer.get_lag(consumer_group)
...
피처 스토어(Feature Store) 장애
온라인 스토어(Online store)는 모든 추론(Inference) 요청의 임계 경로(Critical path)에 있습니다. 시스템이 폴백(Fallback)을 고려하여 설계되지 않았다면, 온라인 스토어의 장애 모드는 전체 서빙 중단으로 이어집니다.
우선순위에 따른 폴백(Fallback) 전략:
-
캐시(Cache)에서 서빙. 서빙 레이어(Serving layer)가 최근에 조회된 피처(Feature)를 캐싱하고 있다면, 최근에 접근했던 엔티티(Entity)들에 대해서는 짧은 온라인 스토어 중단이 사용자 영향 없이 흡수될 수 있습니다.
-
기본값(Defaults) 서빙. 미리 계산된 기본 피처 벡터(Default feature vectors) — 전역 평균(Global averages), 세그먼트 사전 확률(Segment priors), 또는 제로 벡터(Zero vectors) — 를 사용하면 장애 발생 중에도 모델을 낮은 품질로나마 계속 실행할 수 있습니다.
-
우아한 성능 저하(Degrade gracefully). 일부 유스케이스(Use case)의 경우, 품질이 저하된 ML 예측값을 제공하는 것보다 더 단순한 비(非) ML 폴백(가장 인기 있는 아이템, 규칙 기반 결정 등)을 제공하는 것이 더 바람직합니다.
-
빠른 실패(Fail fast). 예측 품질이 매우 중요하여 품질이 저하된 예측을 내놓는 것이 예측을 아예 하지 않는 것보다 나쁜 유스케이스의 경우, 명확한 에러와 함께 명시적으로 실패하는 것이 정답입니다.
적절한 전략은 유스케이스에 따라 다릅니다. 보편적으로 잘못된 상황은 전략이 없는 것입니다. 장애 발생 중에 서빙 레이어에 폴백 경로가 없다는 사실을 발견하고, 압박 속에서 설계를 시작해야 하는 상황 말입니다.
벡터 인덱스(Vector Index) 장애
벡터 인덱스 장애는 일반적으로 이진적(Binary)이지 않습니다. 인덱스가 완전히 다운되는 것이 아니라 성능이 저하됩니다. 재현율(Recall)이 떨어지고, 지연 시간(Latency)이 증가하며, 결과의 관련성(Relevance)이 낮아집니다.
인덱스 성능 저하에 대한 운영적 대응은 이를 어떻게 감지하느냐에 따라 달라집니다:
재현율(Recall)이 임계값 아래로 떨어질 경우: 인덱스 재구축(Rebuild) 또는 컴팩션(Compaction)을 트리거하십시오. 세그먼트 기반 아키텍처(Segment-based architecture)에서는 가장 성능이 저하된 세그먼트들을 컴팩션하는 것만으로도 충분할 수 있습니다. 모놀리식 인덱스(Monolithic index)의 경우 전체 재구축이 필요하며, 이는 재구축 시간 동안 트래픽을 관리해야 함을 의미합니다.
부하 증가 없이 지연 시간(Latency)이 증가하는 경우: 툼스톤(Tombstone) 축적 여부를 확인하십시오. 삭제된 벡터의 비율이 높은 인덱스는 검색 성능(Recall)이 눈에 띄게 저하되기 전에 지연 시간이 먼저 증가하는 양상을 보입니다. 검색 성능이 문제가 되기 전, 즉 조기에 정리(Cleanup)나 재구축(Rebuild)을 실행하는 것이 사후에 대응하는 것보다 비용이 적게 듭니다.
임베딩 모델(Embedding model) 마이그레이션 중: 이중 인덱스 서빙(Dual-index serving) 전략이 가장 안전한 경로입니다. 쿼리를 기존 인덱스와 새 인덱스 모두로 라우팅하되, 결과가 있는 경우 새 인덱스의 결과를 반환하고 아직 재계산되지 않은 레코드에 대해서는 기존 인덱스로 폴백(Fallback)합니다. 마이그레이션 진행률과 두 인덱스 모두에서의 검색 성능(Recall)을 지속적으로 모니터링하십시오.
용량 계획(Capacity Planning): 문제 발생 전 설계하기
실시간 AI 시스템은 규모가 커짐에 따라 예측 가능한 방식으로 실패합니다. 용량 계획(Capacity planning)은 이러한 실패가 발생하기 전에 미리 예측하는 관행입니다.
피처 스토어(Feature store) 용량은 엔티티(Entity) 수, 엔티티당 피처(Feature) 수, 그리고 업데이트 속도라는 세 가지 변수에 의해 결정됩니다. 이 중 어느 하나라도 증가하면 저장 비용과 쓰기 처리량(Write throughput) 요구 사항이 모두 증가합니다. 일반적으로 온라인 스토어(Online store)가 제약 조건(Binding constraint)이 됩니다. 비용이 많이 들고, 용량을 추가하는 데는 계획 시간이 필요하기 때문입니다.
각 변수의 성장을 별도로 모델링하십시오. 사용자 기반에 따라 선형적으로 성장하는 사용자 피처 스토어는 예측 가능합니다. 반면, 활성 사용자가 하루에 많은 피처 업데이트를 생성하는 것과 같이 사용자 활동에 따라 성장하는 스토어는 초선형적(Superlinearly)으로 성장할 수 있습니다. 여러분이 어떤 유형을 보유하고 있는지 파악하십시오.
벡터 인덱스(Vector index) 용량은 벡터 수, 벡터 차원(Dimensionality), 그리고 쿼리 속도(Query rate)에 의해 결정됩니다. HNSW 인덱스의 메모리 요구 사항은 대략 다음과 같습니다:
메모리 (bytes) ≈ num_vectors × (dimension × 4 bytes + M × 8 bytes)
여기서 M은 HNSW 연결성 파라미터(Connectivity parameter, 통상 16-64)입니다.
...
전형적인 임베딩 차원을 가진 1,000만 개의 벡터의 경우, 베이스 벡터 자체를 고려하기 전에 인덱스에만 50-100GB의 메모리가 필요합니다. 한계에 부딪히기 전에 이를 계획하는 것이 압박 속에서 확장하는 것보다 훨씬 저렴합니다.
**추론 컴퓨팅 용량 (Inference compute capacity)**은 가장 친숙한 용량 계획 (capacity planning) 영역이지만, AI 워크로드(workloads)는 많은 웹 워크로드보다 더 급격한 변동(spikier profiles)을 보이는 특성이 있습니다. 모델 추론은 I/O 바운드 (I/O-bound)가 아니라 CPU 또는 GPU 바운드 (CPU or GPU-bound)이므로, 오토스케일링 (autoscaling) 시 웜업 (warmup) 시간이 더 오래 걸린다는 것을 의미합니다. 부하 상황에서 새로운 추론 인스턴스의 콜드 스타트 (cold start)를 유발하지 않고도 급격한 스파이크 (spikes)를 흡수할 수 있는 여유 공간 (headroom)을 고려하여 설계하십시오.
장애 대응: 시스템이 고장 났을 때 해야 할 일
프로덕션 환경에서 실시간 AI 시스템의 성능이 저하될 때, 진단 경로는 구조화되어 있어야 합니다. 이는 엔지니어가 압박 속에서 추론할 능력이 없기 때문이 아니라, 구조화된 진단이 임시방편적인 (ad hoc) 조사보다 더 빠르고 오류가 적기 때문입니다.
실시간 AI 장애를 위한 간단한 의사결정 트리 (decision tree):
엔드 투 엔드 지연 시간 (end-to-end latency)이 높아졌는가?
├── 예 → 컴포넌트별 지연 시간 세부 내역 확인
│ ├── 피처 검색 (Feature retrieval) 지연이 높아졌는가? → 온라인 스토어 (Online store) 상태 확인
...
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기