모니터링 시스템 자체가 죽으면 아무것도 모른다
시계열 데이터베이스를 도입한 팀이 가장 자주 저지르는 실수는 TSDB 자체를 감시하지 않는 것이다. Prometheus가 OOM으로 재시작했다면 그 시간 동안 수집이 멈춰 있었고, 경보는 침묵했다. VictoriaMetrics의 디스크가 가득 차서 새 데이터를 받지 못했을 때 대시보드는 마지막 값을 계속 표시했다.
TSDB 운영자의 첫 번째 책임은 자기 자신을 모니터링하는 것(메타 모니터링)이다. 이 챕터는 Prometheus, VictoriaMetrics, TimescaleDB, InfluxDB의 핵심 운영 지표, 알림 설정, 백업·복구 절차, 그리고 주요 장애 런북을 실용적인 체크리스트 형식으로 정리한다.
메타 모니터링: TSDB 자체를 감시하는 법
Prometheus 자가 스크랩
Prometheus는 자신의 메트릭을 localhost:9090/metrics로 노출한다. 스크랩 설정에 자기 자신을 등록해 두면 수집·저장·평가 상태를 모두 추적할 수 있다.
# prometheus.yml
scrape_configs:
- job_name: 'prometheus'
static_configs:
- targets: ['localhost:9090']핵심 내장 메트릭:
| 메트릭 | 의미 |
|---|---|
prometheus_tsdb_head_series | 현재 활성 시리즈(카디널리티) 수 |
prometheus_tsdb_head_chunks | 헤드 블록 청크 수 |
prometheus_tsdb_compactions_total | 완료된 컴팩션 횟수 |
prometheus_tsdb_compaction_duration_seconds | 컴팩션 소요 시간 |
prometheus_tsdb_wal_corruptions_total | WAL 손상 횟수 |
prometheus_engine_query_duration_seconds | 쿼리 실행 시간 분포 |
scrape_samples_scraped | 타겟별 스크랩 샘플 수 |
up | 스크랩 타겟 활성 여부 (1=UP, 0=DOWN) |
VictoriaMetrics 헬스 엔드포인트
VictoriaMetrics는 /metrics 외에도 /health(상태 확인)와 /vmui 대시보드를 제공한다.
# 기본 상태 확인
curl http://vm-host:8428/health
# 핵심 메트릭 확인
curl -s http://vm-host:8428/metrics | grep -E \
'vm_active_time_series|vm_rows_inserted|vm_cache_size|vm_data_size'| 메트릭 | 의미 |
|---|---|
vm_active_time_series | 최근 1시간 내 업데이트된 시리즈 수 |
vm_rows_inserted_total | 누적 삽입 포인트 수 |
vm_cache_size_bytes{type="indexdb"} | IndexDB 캐시 크기 |
vm_data_size_bytes | 전체 스토리지 사용량 |
vm_slow_row_inserts_total | 느린 삽입 횟수 (메모리 압박 지표) |
vm_slow_queries_total | 타임아웃 임박 쿼리 수 |
TimescaleDB: pg_stat 뷰 활용
TimescaleDB는 PostgreSQL 위에서 동작하므로 표준 pg_stat_* 뷰와 TimescaleDB 전용 뷰를 함께 활용한다.
-- 청크별 크기와 압축 상태
SELECT c.schema_name, c.table_name, c.chunk_name,
pg_size_pretty(c.total_bytes) AS total,
c.is_compressed
FROM timescaledb_information.chunks c
ORDER BY c.total_bytes DESC LIMIT 20;
-- Continuous Aggregate 새로 고침 지연 확인
SELECT view_name, last_run_started_at,
last_successful_finished_at,
last_run_duration
FROM timescaledb_information.continuous_aggregate_stats;
-- 쿼리 성능 현황 (pg_stat_statements 필요)
SELECT query, calls, total_exec_time, mean_exec_time
FROM pg_stat_statements
WHERE query ILIKE '%metrics%'
ORDER BY mean_exec_time DESC LIMIT 10;
-- 백그라운드 작업 상태
SELECT * FROM timescaledb_information.job_stats
WHERE last_run_status = 'Failure';InfluxDB: 내장 메트릭과 헬스 API
InfluxDB 2.x는 /health와 /metrics 엔드포인트를 제공하며, _monitoring 버킷에 자체 메트릭을 자동으로 기록한다.
# 헬스 체크
curl http://localhost:8086/health
# 내부 메트릭 (Prometheus 형식)
curl http://localhost:8086/metrics | grep -E \
'influxdb_tsm_|influxdb_database_|go_memstats_'| 메트릭 | 의미 |
|---|---|
influxdb_tsm_files_total | TSM 파일 수 (컴팩션 상태 반영) |
influxdb_database_num_series | 데이터베이스별 시리즈 수 |
influxdb_tsm_compact_duration_ns | 컴팩션 소요 시간 |
go_memstats_heap_inuse_bytes | JVM 힙 사용량 |
핵심 지표와 알림 임계값
알림 규칙 예시 (Prometheus)
# tsdb-alerts.yml
groups:
- name: tsdb_health
rules:
# 스크랩 타겟 DOWN
- alert: TargetDown
expr: up == 0
for: 5m
labels:
severity: warning
annotations:
summary: "스크랩 타겟 DOWN: {{ $labels.job }}/{{ $labels.instance }}"
# 카디널리티 급증
- alert: CardinalitySpike
expr: |
(prometheus_tsdb_head_series
- prometheus_tsdb_head_series offset 1h)
/ prometheus_tsdb_head_series offset 1h > 0.20
for: 10m
labels:
severity: warning
annotations:
summary: "활성 시리즈 1시간 내 20% 이상 증가"
# 디스크 7일 내 소진 예측
- alert: DiskFillingSoon
expr: |
predict_linear(
prometheus_tsdb_storage_blocks_bytes[6h], 7 * 24 * 3600
) > (node_filesystem_avail_bytes{mountpoint="/prometheus"})
for: 30m
labels:
severity: critical
annotations:
summary: "7일 이내 Prometheus 디스크 소진 예측"
# 쿼리 P99 지연
- alert: QueryLatencyHigh
expr: |
histogram_quantile(0.99,
rate(prometheus_engine_query_duration_seconds_bucket[5m])
) > 10
for: 5m
labels:
severity: warning
annotations:
summary: "쿼리 P99 지연 10초 초과"용량 계획 공식
TSDB의 용량을 예측하는 공식은 단순하지만, 압축률 추정이 핵심이다.
디스크 사용량 예측
일일 디스크 증가량 =
(초당 샘플 수) × (샘플당 바이트) × 86400
현실적인 bytes/sample (Robust Perception 실측 기반):
Prometheus: 1.7~1.8 bytes/sample (실측), 1.3 bytes/sample (이론적 최솟값)
보수적 계획에는 2.0 bytes/sample 사용 권장
VictoriaMetrics: 0.4~0.8 bytes/sample ← Prometheus 대비 2~4× 효율적
InfluxDB (TSM): 1.0~2.0 bytes/sample ← 데이터 특성에 따라 편차 큼
TimescaleDB (압축 활성화): 0.5~1.5 bytes/sample예를 들어 Prometheus 기준, 초당 50만 샘플을 30일 보존한다면:
50만 × 2.0 bytes(보수적 추정) × 86400초 × 30일 ÷ 1e12
= 약 2.6 TB메모리 사용량 예측
Prometheus:
활성 시리즈 1개 = 약 3,000 bytes (헤드 청크 + 레이블 포함)
100만 시리즈 × 3,000 bytes = 약 3 GB (TSDB 헤드만)
실제 RSS는 2~3× 더 클 수 있음 (쿼리 캐시, WAL 버퍼 포함)
VictoriaMetrics:
활성 시리즈 1개 = 약 700 bytes (IndexDB 캐시 포함)
100만 시리즈 × 700 bytes = 약 700 MB용량 임박 전 행동 기준
| 디스크 잔여 | 권장 행동 |
|---|---|
| 30% 이하 | 보존 기간 단기 축소, 불필요한 메트릭 드롭 검토 |
| 15% 이하 | 긴급 보존 기간 축소 또는 스토리지 확장 |
| 7일 이내 소진 예측 | 즉시 에스컬레이션, 인시던트 선언 |
백업과 복구 절차
POST /api/v1/admin/tsdb/snapshot
→ 로컬 snapshots/ 디렉터리에 hard-link 생성
복구: data/ 디렉터리를 snapshot으로 교체 후 재시작
한계: WAL 포함 안 됨. 마지막 2h 데이터 유실 가능
vmbackup -storageDataPath /vm-data -dst s3://bucket/path
증분 백업: -origin 플래그로 이전 백업 기준 증분
복구: vmrestore로 오브젝트 스토리지에서 복원
특징: 일관된 스냅샷, 중단 없이 백업 가능
influx backup /path/to/backup --host http://localhost:8086
복구: influx restore
특징: 버킷 단위 백업 가능, 토큰 별도 보관 필요
장애 대응 런북
런북 1: 카디널리티 폭발 — 활성 시리즈가 급증한다
증상: prometheus_tsdb_head_series가 1시간 이내에 20% 이상 증가. 메모리 사용량 급상승.
# 1. 원인 메트릭 식별
curl -s 'http://localhost:9090/api/v1/status/tsdb' \
| jq '.data.seriesCountByMetricName | to_entries | sort_by(-.value) | .[0:10]'
# 2. 새 레이블 값 확인 (어떤 레이블이 폭발했나)
curl -s 'http://localhost:9090/api/v1/status/tsdb' \
| jq '.data.seriesCountByLabelValuePair | to_entries | sort_by(-.value) | .[0:10]'
# 3. 임시 조치: 문제 타겟 스크랩 중단 또는 metric_relabel_configs로 드롭
# prometheus.yml에 추가:
# metric_relabel_configs:
# - source_labels: [__name__]
# regex: 'problem_metric_.*'
# action: drop복구: 폭발 레이블을 labeldrop으로 제거하고 Prometheus 재시작. 메모리는 TSDB 헤드가 다음 2h 블록 컴팩션 후 감소한다.
런북 2: 수집 중단 — 그래프가 끊어졌다
증상: up == 0 알림 발생. 여러 타겟이 동시에 DOWN.
# 1. 타겟 상태 확인
curl -s http://localhost:9090/api/v1/targets \
| jq '.data.activeTargets[] | select(.health == "down") | {job: .labels.job, instance: .labels.instance, lastError: .lastError}'
# 2. 네트워크 연결 확인
curl -v http://<target-host>:<port>/metrics
# 3. Prometheus 자체 메모리·CPU 확인 (Prometheus OOM?)
ps aux | grep prometheus
dmesg | grep -i oom
# 4. WAL 크기 확인 (비정상적으로 크면 쓰기 중단 신호)
du -sh /prometheus/wal/복구: OOM으로 재시작했다면 카디널리티를 줄이고 메모리를 늘린다. 네트워크 문제라면 방화벽·DNS·서비스 재시작 확인.
런북 3: 쿼리 타임아웃 — 대시보드가 느리거나 오류가 뜬다
증상: Grafana에서 context deadline exceeded 또는 쿼리 패널에 오류.
# 1. 현재 실행 중인 쿼리 확인 (Prometheus)
curl -s http://localhost:9090/api/v1/query_exemplars \
--data 'query=prometheus_engine_queries_concurrent_max'
# 2. 슬로 쿼리 로그 확인
grep "slow_query" /var/log/prometheus/prometheus.log | tail -20
# 3. 원인 쿼리 분석: 범위 쿼리가 너무 넓은가?
# 예: rate(http_requests_total[365d]) → 1년치 raw scan 발생
# 해결: 보존 기간에 맞게 범위 축소 또는 Recording Rules로 사전 집계완화: 문제 쿼리를 --query.max-samples로 제한하거나, Grafana 대시보드의 조회 범위를 줄인다. 장기적으로는 Recording Rules로 미리 집계.
런북 4: 디스크 부족 — 공간이 빠르게 줄고 있다
# 1. 현재 사용량 파악
df -h /prometheus
du -sh /prometheus/data/
# 2. 블록별 크기 확인 (오래된 블록이 남아 있는가?)
ls -lh /prometheus/data/ | sort -k5 -h
# 3. 즉각 조치: 보존 기간 단축 (재시작 필요)
# prometheus.yml 또는 실행 플래그 변경:
# --storage.tsdb.retention.time=7d (기존 15d에서 축소)
# 4. 특정 시계열 삭제 (Admin API 활성화 필요)
curl -X POST -g 'http://localhost:9090/api/v1/admin/tsdb/delete_series' \
--data-urlencode 'match[]=problem_metric{job="legacy"}'
curl -X POST http://localhost:9090/api/v1/admin/tsdb/clean_tombstones운영 체크리스트
일간 점검
| 항목 | Prometheus | VictoriaMetrics | TimescaleDB |
|---|---|---|---|
| 수집 타겟 UP 비율 확인 | up 메트릭 확인 | vmui Targets 탭 | pg_stat_activity |
| 활성 시리즈 수 전일 대비 | head_series | vm_active_time_series | num_chunks 비교 |
| 디스크 여유 공간 | node_filesystem_avail_bytes | vm_data_size_bytes | pg_database_size() |
| 쿼리 P99 지연 | engine_query_duration | vm_request_duration | pg_stat_statements |
| 백업 성공 여부 | snapshot 로그 | vmbackup 로그 | pgBackRest 로그 |
주간 점검
- [ ] 카디널리티 상위 10개 메트릭 검토 및 불필요한 레이블 제거 계획
- [ ] 디스크 사용량 추세 그래프로 3개월 후 용량 예측
- [ ] 슬로 쿼리 상위 5개 확인, Recording Rules 전환 후보 식별
- [ ] 백업 복구 테스트 (스테이징 환경)
- [ ] 컴팩션 지연 또는 비정상 블록 유무 확인
- [ ] 보존 정책이 비용·성능 목표에 맞는지 재검토
월간 점검
- [ ] 전체 메트릭 목록 감사: 더 이상 스크랩되지 않는 타겟 정리
- [ ] TSDB 버전 업그레이드 검토 (최신 보안 패치 및 성능 개선)
- [ ] 고가용성 페일오버 테스트 (클러스터 모드)
- [ ] 알림 규칙 유효성 검토: 너무 자주 울리거나 무시되는 알림 조정
- [ ] 용량 계획 업데이트: 다음 6개월 예산 및 인프라 계획 반영
TSDB 선택별 운영 핵심 차이
| 항목 | Prometheus | VictoriaMetrics | TimescaleDB | InfluxDB 2.x |
|---|---|---|---|---|
| 자가 모니터링 | /metrics 자가 스크랩 | vmui + /metrics | pg_stat_* 뷰 | /metrics + _monitoring 버킷 |
| 백업 방식 | TSDB snapshot API | vmbackup (증분) | pg_basebackup + WAL | influx backup |
| PITR 지원 | 불가 | 불가 | 가능 (WAL 아카이브) | 불가 |
| 클러스터 모니터링 | 별도 Thanos/Mimir | 내장 (Cluster 메트릭) | Patroni/pgBouncer 연동 | InfluxDB Cloud 제공 |
| 컴팩션 튜닝 | 수동 불가 (자동) | 자동 (LSM 병합) | 수동 압축 설정 | 자동 (수동 컴팩션 가능) |
References
- Prometheus Best Practices: Metric Naming and Labels
- Prometheus TSDB Format Documentation
- VictoriaMetrics Operations Guide
- VictoriaMetrics vmbackup Documentation
- TimescaleDB Administration Guide
- TimescaleDB: Continuous Aggregates
- InfluxDB 2.x Backup and Restore
- Robust Perception: How much disk space do Prometheus metrics take up?
- Google SRE Book: Monitoring Distributed Systems