LLM WikiAccess-protected knowledge portal
← 스터디 홈
6편 · 약 24분

운영과 모니터링 체크리스트

모니터링 시스템 자체가 죽으면 아무것도 모른다

시계열 데이터베이스를 도입한 팀이 가장 자주 저지르는 실수는 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_totalWAL 손상 횟수
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_totalTSM 파일 수 (컴팩션 상태 반영)
influxdb_database_num_series데이터베이스별 시리즈 수
influxdb_tsm_compact_duration_ns컴팩션 소요 시간
go_memstats_heap_inuse_bytesJVM 힙 사용량

핵심 지표와 알림 임계값

TSDB 모니터링 지표 계층 수집(Ingestion) — 데이터가 제대로 들어오고 있는가 • scrape_duration_seconds (스크랩 지연) • up == 0 (타겟 DOWN) • samples/sec (수집 속도 → 기준선 대비 -30% 이상 경보) • WAL 크기 (정상: 2시간치 데이터 이내) • 스크랩 실패율 (> 5% → 경보) 저장(Storage) — 디스크·메모리·카디널리티 • 활성 시리즈 수 (전일 대비 +20% → 경보) • 디스크 여유 공간 (7일 이내 소진 예상 → 경보) • 메모리 RSS (힙 사용률 > 80% → 경보) • 컴팩션 지연 (큐 적재 → 디스크 임시 급증 신호) 쿼리(Query) — 읽기 성능 • query P99 (> 10s → 경보) • 슬로 쿼리 수 (> 기준선 2× → 경보) • 쿼리 실패율 (> 1% → 경보) • 동시 쿼리 수 (한계 대비 80% → 경보) 백업·가용성(Backup/Availability) • 마지막 백업 성공 시각 (24h 이상 없으면 경보) • 복제 지연 (클러스터 모드) (> 30s → 경보) • 백업 크기 이상(전일 대비 2× 이상 → 확인) • 스냅샷 완료 시간 (SLA 기준 이내 여부)
핵심 모니터링 지표 계층

알림 규칙 예시 (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일 이내 소진 예측즉시 에스컬레이션, 인시던트 선언

백업과 복구 절차

Prometheus 백업: Admin API /snapshot POST /api/v1/admin/tsdb/snapshot → 로컬 snapshots/ 디렉터리에 hard-link 생성 복구: data/ 디렉터리를 snapshot으로 교체 후 재시작 한계: WAL 포함 안 됨. 마지막 2h 데이터 유실 가능
VictoriaMetrics 백업: vmbackup 도구 vmbackup -storageDataPath /vm-data -dst s3://bucket/path 증분 백업: -origin 플래그로 이전 백업 기준 증분 복구: vmrestore로 오브젝트 스토리지에서 복원 특징: 일관된 스냅샷, 중단 없이 백업 가능
TimescaleDB 논리 백업: pg_dump + pg_restore 물리 백업: pgBackRest / pg_basebackup + WAL 아카이브 PITR: WAL 아카이빙으로 임의 시점 복구 주의: 압축 청크는 pg_dump 전에 decompress 후 백업 권장
InfluxDB 2.x 백업: influx backup 명령 influx backup /path/to/backup --host http://localhost:8086 복구: influx restore 특징: 버킷 단위 백업 가능, 토큰 별도 보관 필요
공통 원칙: 백업 후 반드시 복구 테스트를 수행한다. 복구 불가능한 백업은 없는 것과 같다. 최소 분기 1회, 가능하면 월 1회 스테이징 환경에서 실제 복구를 검증한다.
백업 유형과 복구 경로

장애 대응 런북

런북 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

운영 체크리스트

일간 점검

항목PrometheusVictoriaMetricsTimescaleDB
수집 타겟 UP 비율 확인up 메트릭 확인vmui Targets 탭pg_stat_activity
활성 시리즈 수 전일 대비head_seriesvm_active_time_seriesnum_chunks 비교
디스크 여유 공간node_filesystem_avail_bytesvm_data_size_bytespg_database_size()
쿼리 P99 지연engine_query_durationvm_request_durationpg_stat_statements
백업 성공 여부snapshot 로그vmbackup 로그pgBackRest 로그

주간 점검

  • [ ] 카디널리티 상위 10개 메트릭 검토 및 불필요한 레이블 제거 계획
  • [ ] 디스크 사용량 추세 그래프로 3개월 후 용량 예측
  • [ ] 슬로 쿼리 상위 5개 확인, Recording Rules 전환 후보 식별
  • [ ] 백업 복구 테스트 (스테이징 환경)
  • [ ] 컴팩션 지연 또는 비정상 블록 유무 확인
  • [ ] 보존 정책이 비용·성능 목표에 맞는지 재검토

월간 점검

  • [ ] 전체 메트릭 목록 감사: 더 이상 스크랩되지 않는 타겟 정리
  • [ ] TSDB 버전 업그레이드 검토 (최신 보안 패치 및 성능 개선)
  • [ ] 고가용성 페일오버 테스트 (클러스터 모드)
  • [ ] 알림 규칙 유효성 검토: 너무 자주 울리거나 무시되는 알림 조정
  • [ ] 용량 계획 업데이트: 다음 6개월 예산 및 인프라 계획 반영

TSDB 선택별 운영 핵심 차이

항목PrometheusVictoriaMetricsTimescaleDBInfluxDB 2.x
자가 모니터링/metrics 자가 스크랩vmui + /metricspg_stat_* 뷰/metrics + _monitoring 버킷
백업 방식TSDB snapshot APIvmbackup (증분)pg_basebackup + WALinflux backup
PITR 지원불가불가가능 (WAL 아카이브)불가
클러스터 모니터링별도 Thanos/Mimir내장 (Cluster 메트릭)Patroni/pgBouncer 연동InfluxDB Cloud 제공
컴팩션 튜닝수동 불가 (자동)자동 (LSM 병합)수동 압축 설정자동 (수동 컴팩션 가능)

References