고카디널리티 레이블은 왜 Prometheus를 먹통으로 만드는가?

Prometheus의 OOM 사건은 대부분 시계열(time series) 수의 곱셈적 폭발에서 비롯된다. 하나의 메트릭에 고유값이 많은 레이블을 추가하면 시계열 수는 기존 카디널리티 × 새 레이블의 고유값 개수로 증가하고, 이는 곧 인메모리 인덱스 부하로 전환된다.

  • 시계열 수 폭발: 레이블 추가 시 카디널리티가 곱셈적으로 증가하며 즉시 메모리 할당 부담으로 직결
  • OOM의 직접 원인: 사용자 ID, 요청 ID, IP 주소 등 무한 변하는 값을 레이블화할 경우 메모리 사용량이 기하급수적으로 증가
  • 재기동 페널티: WAL 복구 단계에서 OOM이 발생하면 Prometheus는 정상 기동에 실패하고 반복된 OOMKilled 루프에 진입

시계열 폭발의 메커니즘은 무엇인가?

Prometheus의 메모리 구조를 정리하면, 각 메트릭-레이블 조합이 독립적인 시계열 객체로 메모리에 적재된다. 예를 들어 http_requests_total 메트릭에 method, status, endpoint 레이블이 있다면, 메모리에 올라가는 시계열 수는 method 값 개수 × status 값 개수 × endpoint 값 개수이다.

AWS AMP 공식 문서에서 언급된 수집 비용 구조에 따르면, 카디널리티를 줄이는 것이 메모리 효율의 가장 직접적인 방법이다. Kubernetes 환경에서 파드 수가 동적으로 변할 때 각 파드 인스턴스를 instance 레이블로 구분하면, 파드 수가 1,000개를 넘어가는 순간 같은 메트릭의 시계열이 수천 개 단위로 증가한다.

이 문제는 **레이블 값의 범주성(Cardinality Bound)**이 없을 때 발생한다. method="GET/POST", status="200/500" 같은 제한된 범주형 레이블은 안전하지만, user_id, email, trace_id 같은 무한 변하는 값을 레이블로 사용하면 시계열은 제어 불가능한 속도로 증가한다.

WAL 복구는 왜 OOM 트리거가 되는가?

Prometheus가 비정상 종료된 후 재기동할 때, WAL(Write-Ahead Log) 복구 단계에서 OOM이 가장 흔하게 발생한다. 이유는 인메모리 버퍼가 WAL 파일의 누적된 메트릭 데이터를 모두 로드해야 하기 때문이다.

실제 사례로, Kubernetes 환경에서 메모리 8Gi를 할당받은 Prometheus 인스턴스가 대량 파드 생성 이후 OOM 에러로 강제 종료된 뒤 다시 시작할 때 WAL 복구 단계에서 재차 OOMKilled되는 현상이 보고되었다. 메모리를 16Gi로 증설한 뒤 정상 기동 확인 후, WAL 파일을 정리(compaction)하면 원래 8Gi 할당에서도 안정적으로 동작하게 되었다(실제 운영 사례).

이 메커니즘은 다음과 같이 작동한다:

  1. Prometheus 프로세스가 OOM으로 종료됨
  2. 재기동 시 WAL 파일에서 마지막 상태까지의 모든 시계열을 메모리에 복원 시도
  3. WAL 파일이 고카디널리티로 가득 차 있으면, 할당된 메모리를 초과하는 순간 다시 OOMKilled 발생
  4. 이 루프가 반복되면 Prometheus는 영구히 기동 불가 상태에 빠짐

WAL 복구 부하를 줄이려면 주기적인 TSDB 스냅샷 생성과 레이블 카디널리티 감사가 필수다.

TSDB Status로 고카디널리티 범인을 식별하는 방법은?

Prometheus의 내부 Status 페이지(http://<prometheus>:9090/tsdb)에서 "Top 10 series count by metric name" 섹션을 보면 메모리를 가장 많이 차지하는 메트릭들을 즉시 파악할 수 있다. 또한 메트릭 prometheus_tsdb_head_series의 값이 현재 로드된 시계열의 총 개수를 나타낸다.

실제 운영에서 고카디널리티 문제가 의심될 때는 다음 체크리스트를 따른다:

  • Cardinality API 호출: /api/v1/label/<label_name>/values 엔드포인트로 특정 레이블의 고유값 개수 조회
  • 메트릭별 시계열 개수: prometheus_tsdb_head_series 메트릭 쿼리로 전체 규모 파악
  • Top N 메트릭 확인: TSDB Status의 "Top 10 series count"에서 예상 외로 높은 메트릭 발견
  • 레이블 값 감사: 범주형이 아닌 값(ID, timestamp, UUID)이 레이블화되지 않았는지 확인

Prometheus 로그에서도 경고가 나타난다. 카디널리티가 임계값을 넘으면 cardinality limit exceeded 에러가 기록되며, 이는 데이터 스크래핑 자체가 거부된다는 뜻이다.

eBPF 무계측 수집이 역설적으로 고카디널리티를 증폭시키는 이유는?

2025년 기준으로 eBPF 기반 에이전트(Pixie, Beyla 등)는 코드 변경 없이 네트워크 패킷, 시스템 호출, CPU 샘플링을 자동으로 수집한다. 이는 관측성 인프라 구축 비용을 급격히 줄인다는 장점이 있다.

그러나 트레이드오프가 있다. eBPF는 자동으로 생성된 레이블이 예상치 못한 고카디널리티를 초래할 수 있다. 예를 들어 네트워크 트래픽을 추적하면 src_ip, dst_ip, src_port, dst_port가 자동으로 레이블화되는데, 이들은 각각 수천 개의 고유값을 가질 수 있다. 커널 함수명을 프로파일링하는 경우 함수 이름도 레이블이 되어 카디널리티를 폭발시킨다.

eBPF 수집의 또 다른 트레이드오프는 커버리지와 비용의 비대칭성이다. 네트워크·시스템 호출 레벨에서는 높은 커버리지를 제공하지만, 코드 레벨 세밀 추적(예: 함수 호출 계수, 로컬 변수 값)은 eBPF의 기술적 한계로 인해 낮은 커버리지를 보인다. 동시에 자동 수집으로 인한 오버헤드와 메모리 부담은 레이블 필터링 전략 없이는 통제 불가능하다.

이를 방지하려면 eBPF 에이전트 설정 단계에서 레이블 화이트리스트와 정규화(Relabeling) 규칙을 미리 정의해야 한다. 예를 들어 dst_port는 수집 대상에서 제외하거나, 포트를 서비스명으로 변환하는 매핑을 적용한다.

카디널리티 제어의 실전 경계는 어디인가?

고카디널리티 문제는 레이블 설계 단계에서 방어해야 하며, 사후 대응은 비용이 훨씬 크다.

적용하지 말아야 할 경우:

  • 무한 변하는 값을 레이블로 사용: user_id, request_id, trace_id, timestamp, IP 주소, email 등은 절대 레이블화하지 말 것. 이들은 Exemplars로 연결하거나 로그로 전달해야 한다.
  • 범주형이 아닌 수치를 레이블화: 응답 시간, 바이트 수, 요청 크기 등은 메트릭의 값(value)으로 저장하고, 필요하면 히스토그램으로 버킷화할 것.

적용해야 할 경우:

  • 제한된 범주형 값만: method="GET/POST/PUT/DELETE", status="200/400/500", region="us-east/eu-west" 등 고유값이 10개 이하인 레이블만 사용
  • Recording Rules로 계산 결과 캐싱: 고카디널리티 쿼리가 필요한 경우 미리 계산 규칙을 정의하면 쿼리 속도가 수십 배 빨라지고 메모리 부하가 감소
  • scrape_interval 조정: 15초에서 30초로 연장하면 수집 빈도가 절반으로 줄어 메모리 증가 속도 제어 가능

핵심 정리

  • 시계열 수의 곱셈적 폭발: 레이블 추가 시 카디널리티는 곱셈으로 증가하며, 무한 변하는 값을 레이블화하면 메모리 제어 불가능
  • WAL 복구의 OOM 트리거: Prometheus 비정상 종료 후 재기동 시 WAL 복구 단계에서 OOM이 발생하면 반복된 강제 종료 루프에 빠짐. 8Gi 할당에서 16Gi로 증설 후 안정화된 실제 사례 존재
  • eBPF의 자동 레이블화 위험: 무계측 수집의 편리성은 예상치 못한 고카디널리티 레이블(IP, 포트, 함수명)을 초래할 수 있으므로, 설정 단계에서 Relabeling 필터링 필수
  • TSDB Status와 Cardinality API: 메트릭별 시계열 개수와 레이블 고유값을 실시간 모니터링하는 것이 가장 효과적인 예방법
  • 사후 대응 비용 > 설계 단계 방어: 레이블 추가 전 범주성 확인, 주기적 감사, Recording Rules 활용이 메모리 오버플로우를 방지하는 핵심

더 알아보기

관측성 파이프라인 설계: 메트릭·로그·트레이스 수집의 실제 — 이 주제의 종합 가이드