왜 로컬 TSDB만으로는 부족한가
Prometheus의 로컬 TSDB는 단일 노드에 묶여 있고 기본 보존 기간이 15일이다. 장애 원인 분석이나 용량 계획을 위해 수개월 전 데이터를 봐야 하는 순간, 로컬 저장소는 두 가지 한계를 드러낸다. 첫째, 디스크 용량이 보존 기간을 선형적으로 제약한다. 둘째, Prometheus 인스턴스가 죽으면 그 데이터도 함께 사라진다. remote write는 수집된 샘플을 Thanos, Mimir, VictoriaMetrics 같은 외부 장기 저장소로 흘려보내 이 문제를 분리한다.
remote write는 어떻게 동작하는가
Prometheus는 로컬 TSDB의 WAL(Write-Ahead Log)을 읽어 샘플을 원격지로 전송한다. 핵심은 큐 기반 비동기 전송이라는 점이다. 각 shard는 내부 큐에 샘플을 쌓고 HTTP로 배치 전송한다. 원격지가 느려지면 큐가 차고, 큐가 임계치를 넘으면 shard 수를 자동으로 늘려 처리량을 따라잡으려 한다. 이 동작을 이해하지 못하면 메모리 폭증이나 샘플 유실을 원격지 탓으로 오해하기 쉽다.
큐 튜닝: 처리량과 메모리의 균형
기본값은 소규모 환경 기준이라 카디널리티가 높은 클러스터에서는 큐가 밀린다. prometheus_remote_storage_samples_pending와 prometheus_remote_storage_shards가 상한에 붙어 있다면 튜닝이 필요하다.
remote_write:
- url: https://longterm.example.com/api/v1/write
queue_config:
capacity: 10000 # shard당 큐 크기
max_shards: 50 # 최대 병렬 shard
min_shards: 4
max_samples_per_send: 2000
batch_send_deadline: 5s
min_backoff: 100ms
max_backoff: 5s
metadata_config:
send: true
send_interval: 1m
max_samples_per_send를 키우면 요청당 오버헤드가 줄지만 원격지의 배치 제한을 넘으면 413/400이 난다. 원격지 권장값을 먼저 확인하고 맞춰야 한다.
전송 전에 줄여라: relabel로 카디널리티 통제
장기 저장 비용의 대부분은 카디널리티에서 나온다. 디버깅용 고카디널리티 메트릭까지 전부 원격지로 보낼 이유는 없다. write_relabel_configs로 전송 단계에서 걸러내는 것이 가장 효과적이다.
remote_write:
- url: https://longterm.example.com/api/v1/write
write_relabel_configs:
# go 런타임 세부 메트릭은 장기 저장 제외
- source_labels: [__name__]
regex: "go_gc_.*|go_memstats_.*"
action: drop
# 임시 파드 id 라벨 제거로 시계열 폭증 방지
- regex: "pod_template_hash|controller_revision_hash"
action: labeldrop
주의할 점은 labeldrop이 시계열 병합을 유발한다는 것이다. 제거한 라벨로 구분되던 두 시계열이 하나로 합쳐지면 카운터가 뒤섞여 rate 계산이 깨질 수 있다. 반드시 집계 관점에서 안전한 라벨만 지운다.
장기 저장소 선택 기준
백엔드마다 저장 모델과 운영 부담이 다르다. 실무 선택은 대개 다음 축으로 갈린다.
| 항목 | Thanos | Mimir | VictoriaMetrics |
|---|---|---|---|
| 저장 방식 | 객체 스토리지 + sidecar | 객체 스토리지 네이티브 | 자체 포맷(로컬/클러스터) |
| 운영 복잡도 | 중간 | 높음 | 낮음 |
| 압축 효율 | 중간 | 중간 | 높음 |
| 적합 규모 | 중소~대 | 대규모 멀티테넌트 | 단일~중규모 |
객체 스토리지 기반은 저장 비용이 저렴하지만 쿼리 지연이 길고, 자체 포맷은 압축률과 쿼리 속도가 좋지만 스토리지 운영을 직접 떠안는다.
다운샘플링과 보존 정책
원본 해상도(예: 15초 간격)를 수개월 보관하면 용량이 감당되지 않는다. 다운샘플링은 오래된 데이터를 5분·1시간 해상도로 재집계해 저장량을 줄인다. Thanos compactor 기준 설정은 다음과 같다.
thanos compact \
--data-dir=/var/thanos/compact \
--objstore.config-file=bucket.yaml \
--retention.resolution-raw=30d \
--retention.resolution-5m=180d \
--retention.resolution-1h=2y
단, 다운샘플링은 순간 스파이크를 뭉갠다. SLO 위반처럼 짧은 이상치를 봐야 하는 구간은 raw 해상도 보존 기간 안에 있어야 한다. 보존 정책은 스토리지 비용이 아니라 조사 요구사항에서 역산하는 것이 맞다.
운영 시 놓치기 쉬운 지점
remote write는 로컬 TSDB를 대체하지 않는다. 원격지 장애 시 WAL이 버퍼 역할을 하지만 wal_truncate 시점을 넘긴 데이터는 복구되지 않으므로, 로컬 보존 기간을 최소 수 시간은 남겨 둬야 한다. 또한 원격지 다운타임 동안 쌓인 샘플이 복구 시 한꺼번에 몰리면 큐가 터지므로 max_backoff와 max_shards를 함께 봐야 한다. 마지막으로 prometheus_remote_storage_samples_failed_total과 큐 pending 지표는 반드시 알람으로 걸어 조용한 유실을 막는다.