시계열 데이터베이스 개요: 왜 범용 DB로는 부족한가
시계열 데이터란 무엇인가
시계열 데이터(time-series data)는 시간 순서로 기록된 측정값의 연속이다. 서버 CPU 사용률, 온도 센서 값, 주가 틱, HTTP 요청 레이턴시, IoT 장치 전력 소비량 같은 데이터가 여기에 해당한다. 공통점은 다음과 같다.
- 쓰기가 압도적으로 추가(append-only) 방식이다.
- 타임스탬프가 기본 조회 키다.
- 최근 데이터를 가장 자주 조회하고, 오래된 데이터는 집계·다운샘플링 후 보관하거나 삭제한다.
- 단건 포인트 업데이트나 삭제는 거의 없다.
- 같은 소스에서 초당 수백~수만 건의 데이터가 지속 유입된다.
이러한 특성이 범용 관계형 DB에는 맞지 않는다. 이 글에서는 그 이유와 TSDB가 어떻게 다르게 설계되었는지 살펴본다.
RDBMS가 시계열 워크로드에서 무너지는 이유
문제 1: 단일 대형 테이블의 인덱스 비용
metrics 테이블에 컬럼 (timestamp, host, metric_name, value)가 있다고 하자. 초당 10,000건 삽입이면 하루 8.6억 행이다. B-Tree 인덱스는 삽입 시마다 리프 노드를 재조정하고, 트리 높이가 증가할수록 쓰기 지연이 늘어난다. 1년이 지나면 인덱스 자체가 수십 GB를 차지하고, WHERE timestamp BETWEEN ... AND ... 쿼리도 느려진다.
문제 2: 시간 기반 파티셔닝의 수작업 관리
파티셔닝으로 시간 범위를 분리하면 쿼리 pruning이 가능하다. 그러나 "이번 달 파티션 생성", "3개월 지난 파티션 삭제", "파티션 경계 조정" 등이 운영자 수작업이 된다. 데이터가 성장하면서 이 관리 부담이 선형적으로 늘어난다.
문제 3: 행 기반 저장의 집계 비효율
SELECT avg(value), host FROM metrics WHERE timestamp > now() - INTERVAL '1 hour' GROUP BY host 같은 쿼리는 각 행의 timestamp·host·metric\_name·value를 모두 읽는다. 필요한 것은 value 컬럼뿐인데, 행 기반 저장에서는 불필요한 컬럼까지 디스크에서 읽어야 한다.
문제 4: 보존 정책과 다운샘플링 미지원
시계열 데이터는 보통 최근 7일은 원본 해상도, 30일은 1분 집계, 1년은 1시간 집계로 보관한다. RDBMS에는 이 기능이 내장되어 있지 않아 스케줄러·트리거·배치 잡으로 직접 구현해야 한다.
문제 5: 시계열에 최적화되지 않은 압축
타임스탬프는 단조 증가하므로 델타 인코딩(연속 값의 차이만 저장)으로 극적으로 압축할 수 있다. 부동소수점 시계열은 XOR 압축(Gorilla 알고리즘)으로 원본 대비 10분의 1 이하로 줄이기도 한다. 범용 RDBMS는 이런 시계열 특화 압축을 지원하지 않는다.
TSDB 데이터 모델
대부분의 TSDB는 다음 세 가지 개념으로 데이터를 표현한다.
cpu_usage{host="web-01", region="ap-northeast-2"}시리즈 = 측정 이름 + 태그 조합의 고유 식별자. 각 시리즈는 독립적인 시간 순서 데이터 스트림이다.
시리즈 카디널리티(Series Cardinality)는 시스템이 추적하는 시리즈의 총 수다. host가 1,000개, region이 10개, env가 3개이면 카디널리티는 30,000이다. 여기에 user_id(100만 개)를 태그로 추가하면 카디널리티가 300억으로 폭발한다. 대부분의 TSDB는 시리즈 인덱스를 메모리에 유지하므로 카디널리티 폭발은 메모리 고갈로 직결된다.
TSDB 내부 저장 구조: 청크와 시간 파티션
TSDB는 데이터를 시간 윈도우 단위 청크로 나누어 저장한다. 각 청크는 특정 시간 범위의 데이터만 포함하고, 독립적으로 압축·삭제·아카이브된다.
이 구조 덕분에:
- 쿼리:
WHERE time > now() - 7d조건이 있으면 이전 청크는 완전히 건너뛴다. - 압축: 오래된 청크를 플러시·압축해도 활성 쓰기에 영향이 없다.
- 삭제: 청크 단위로 파일을 삭제하면 되므로 RDBMS의 행 단위
DELETE보다 훨씬 빠르다.
시계열 압축 알고리즘
TSDB는 시계열 데이터의 패턴을 이용해 범용 압축보다 훨씬 높은 비율을 달성한다.
타임스탬프 압축 (Delta-of-Delta)
타임스탬프가 규칙적으로 증가한다면, 첫 번째 차이(delta)는 거의 일정하다. 그 차이의 차이(delta-of-delta)는 0에 가까워 매우 적은 비트로 표현된다. Facebook의 Gorilla 논문에서 제안했으며, 초당 데이터처럼 주기적인 시계열에서 타임스탬프 크기를 1/10 이하로 줄인다.
부동소수점 값 압축 (XOR / Gorilla)
연속된 두 부동소수점 값을 XOR하면, 값이 비슷할수록 선두 0(leading zeros)이 많다. 이 특성을 이용해 변화분만 저장한다. CPU 사용률, 온도처럼 완만하게 변화하는 값에 효과적이다.
TSDB별 압축 특성
| 엔진 | 타임스탬프 | 숫자 값 | 문자열 |
|---|---|---|---|
| InfluxDB v3 (IOx) | Delta-of-delta | Parquet 인코딩 | Dictionary |
| TimescaleDB | PostgreSQL TOAST | zstd 컬럼 압축 | PostgreSQL 기본 |
| VictoriaMetrics | Delta-of-delta | XOR + Gorilla 변형 | 없음(태그만) |
| Prometheus | Delta-of-delta | XOR (Gorilla) | 없음 |
카디널리티: TSDB 운영의 핵심 제약
카디널리티가 높으면 시리즈 인덱스가 메모리를 잠식한다. 실무에서 자주 저지르는 실수와 올바른 패턴을 정리한다.
method="GET",
path="/api/v1/users",
user_id="1234567", ← NG
request_id="abc-xyz" ← NG
}
method="GET",
path="/api/v1/users",
status_code="200",
region="ap-northeast-2"
}
태그 vs 필드 선택 기준:
- 태그: 그룹핑·필터링 대상, 카디널리티 낮음 (host, region, env, status_code)
- 필드: 측정값, 분석 대상, 카디널리티 제한 없음 (value, response_time_ms, byte_count)
주요 TSDB 생태계
현재 운영 환경에서 가장 많이 쓰이는 TSDB를 한눈에 비교한다.
| 엔진 | 특징 | 주 사용 사례 |
|---|---|---|
| Prometheus | Pull 기반, 로컬 저장, 단기 보존 | Kubernetes 메트릭 수집 |
| VictoriaMetrics | Prometheus 호환, 고압축, 낮은 메모리 | Prometheus 장기 원격 스토리지 |
| InfluxDB v3 | SQL/InfluxQL, Apache Arrow/DataFusion 기반 | 범용 시계열, IoT |
| TimescaleDB | PostgreSQL 확장, 관계형 JOIN 가능 | 시계열 + 관계형 혼합 |
| OpenTSDB | HBase 기반, 수평 확장 | 레거시 대규모 환경 |
| QuestDB | 초고속 쓰기, SQL 지원 | 금융 틱 데이터 |
Prometheus는 "스크랩→단기 저장→알림" 역할에 특화되어 있고, 장기 저장은 VictoriaMetrics나 Thanos 같은 원격 스토리지에 위임하는 것이 일반적인 운영 패턴이다.
언제 TSDB를 도입할 것인가
모든 시계열 데이터에 TSDB가 필요한 것은 아니다. 다음 기준으로 판단한다.
TSDB 도입이 정당화되는 상황:
- 초당 수천 건 이상의 지속 쓰기가 있고, 단순 INSERT 후 오래된 데이터 삭제가 반복된다.
GROUP BY time(1m)같은 시간 버킷 집계가 핵심 쿼리다.- 데이터 보존 정책(30일 원본, 1년 1분 집계)이 명확하고 자동화가 필요하다.
- 단순 행 수가 수십억 이상으로 RDBMS 파티셔닝으로 감당하기 어려워지는 시점.
RDBMS로도 충분한 상황:
- 메트릭 종류가 수십 개 이하, 수집 주기가 분 단위, 보존 기간이 수개월 이하다.
- 시계열 데이터를 다른 관계형 테이블과 JOIN해야 한다. (TimescaleDB가 교량 역할을 할 수 있다)
- 팀에 TSDB 운영 경험이 없고, 관리 오버헤드 추가가 부담이다.
이 시리즈에서 다룰 내용
다음 장부터 주요 TSDB를 하나씩 깊이 파고든다.
- 2장: InfluxDB v3 아키텍처 — IOx 스토리지 엔진, Apache Arrow 기반 쿼리, 스키마 설계
- 3장: TimescaleDB — PostgreSQL 확장 방식, 하이퍼테이블, 연속 집계(Continuous Aggregate)
- 4장: VictoriaMetrics — 클러스터 아키텍처, Prometheus 장기 저장소 운영 패턴
- 5장: 시계열 데이터 모델링 — 카디널리티 관리, 다운샘플링 전략, 보존 정책 설계
- 6장: 운영 체크리스트 — 모니터링 지표, 장애 패턴, 용량 계획
References
- InfluxData: Time Series Data, Cardinality, and InfluxDB, https://www.influxdata.com/blog/time-series-data-cardinality-influxdb/
- Gorilla: A Fast, Scalable, In-Memory Time Series Database (Facebook, VLDB 2015), https://www.vldb.org/pvldb/vol8/p1816-teller.pdf
- TigerData: Time-Series Database — What It Is, How It Works, and When You Need One, https://www.tigerdata.com/learn/time-series-database-what-it-is-how-it-works-and-when-you-need-one
- Alibaba Cloud: Time Series Database Solution to the Problem of High Cardinality, https://www.alibabacloud.com/blog/time-series-database-solution-to-the-problem-of-timeline-expansion-high-cardinality_598694
- Nova AI Ops Blog: Prometheus vs InfluxDB vs VictoriaMetrics 2026 Comparison, https://novaaiops.com/blog/prometheus-vs-influxdb-vs-victoriametrics-2026
- Aliaksandr Valialkin: High-cardinality TSDB benchmarks — VictoriaMetrics vs TimescaleDB vs InfluxDB, https://valyala.medium.com/high-cardinality-tsdb-benchmarks-victoriametrics-vs-timescaledb-vs-influxdb-13e6ee64dd6b
- Prometheus 공식 문서 — Storage, https://prometheus.io/docs/prometheus/latest/storage/
- VictoriaMetrics 공식 문서, https://docs.victoriametrics.com/