백엔드 데이터 인프라 76편 — Redis Time Series (TS.ADD · Labels · Compaction)

2026-05-17백엔드 데이터 인프라

백엔드 데이터 인프라 76편. Redis Time Series 모듈 — 시계열 데이터 native 지원. TS.CREATE·TS.ADD·TS.RANGE·TS.MRANGE·TS.CREATERULE 명령어와 Prometheus 스타일 labels, retention/compaction rule, InfluxDB·TimescaleDB·Prometheus 와의 비교까지 풀어쓴 학습 노트.

📚 백엔드 데이터 인프라 · 76편 — Redis Time Series (TS.ADD · Labels · Compaction)

이 글은 백엔드 데이터 인프라 시리즈 130편 중 76편이에요. 75편 에서 RediSearch(Redis 의 전문 검색 모듈) 검색·집계를 잡았다면, 이번 76편은 Redis Time Series — 시계열 데이터(timestamp + value)를 다루는 native 지원 모듈이에요. 모니터링·IoT·금융 시계열 분야에서 씁니다.

Redis Time Series가 어렵게 느껴지는 이유

"이건 Sorted Set 으로 풀 수 있는 거 아닌가요?" 가 첫 의문이에요. 답은 "가능하지만 효율과 기능에서 큰 차이".

첫째, 별도 모듈이 필요한 이유부터. Sorted Set 으로 시계열을 흉내내는 건 가능하지만 Gorilla 압축(Facebook 의 시계열 압축 알고리즘), 자동 retention(데이터 자동 만료), downsampling(저빈도로 자동 집계) 같은 시계열 특화 기능이 빠져요.

둘째, Prometheus 스타일 labels. 각 시리즈에 multi-dimensional(다차원) 라벨을 박고 그 라벨로 집계·필터링을 합니다. Prometheus·InfluxDB 가 쓰는 모델과 같아요.

이 글에서 Time Series 의 핵심 명령어, labels 모델, retention, compaction, 인기 시계열 DB 와의 비교까지 한번에 짚어요.

핵심 명령어

TS.CREATE — 시리즈 생성

> TS.CREATE temperature:tlv RETENTION 86400000 LABELS city tlv sensor 1
OK
  • RETENTION <ms> = 데이터 보관 기간 (24시간)
  • LABELS = key-value 라벨 (Prometheus 스타일)
  • ENCODING COMPRESSED (기본) = Gorilla 압축 / UNCOMPRESSED = 원본

TS.ADD — 샘플 추가

> TS.ADD temperature:tlv * 25.5
(integer) 1747475123456            # 부여된 timestamp (ms)

> TS.ADD temperature:tlv 1747475200000 26.0
(integer) 1747475200000

* 는 현재 시간을 자동으로 박아줘요.

TS.MADD — 여러 시리즈 동시 추가

> TS.MADD \
    temperature:tlv * 25.5 \
    temperature:nyc * 18.3 \
    humidity:tlv * 60

여러 메트릭을 한 호출에 담을 수 있어요.

TS.RANGE — 시간 범위 조회

> TS.RANGE temperature:tlv - +
1) 1) (integer) 1747475123456
   2) 25.5
2) 1) (integer) 1747475200000
   2) 26.0

- 는 가장 오래된 시각, + 는 가장 최신.

집계 옵션도 같이 줄 수 있어요:

# 5분 단위 평균
> TS.RANGE temperature:tlv - + AGGREGATION avg 300000

집계 함수는 avg·min·max·sum·count·first·last·range·std.s·std.p·var.s·var.p 가 있습니다.

TS.MRANGE — 여러 시리즈 라벨 기반 조회

# 모든 city=tlv 의 시리즈
> TS.MRANGE - + FILTER city=tlv

# city=tlv 의 모든 시리즈 5분 평균
> TS.MRANGE - + AGGREGATION avg 300000 FILTER city=tlv

Prometheus 의 PromQL(Prometheus 쿼리 언어) 과 비슷한 라벨 필터예요.

TS.GET / TS.MGET — 최신 값

> TS.GET temperature:tlv
1) (integer) 1747475200000
2) 26.0

> TS.MGET FILTER city=tlv

TS.CREATERULE — 자동 Downsampling

# raw 시리즈
> TS.CREATE temperature:tlv RETENTION 3600000     # 1시간만 보관

# 1분 평균 destination
> TS.CREATE temperature:tlv:1min RETENTION 86400000    # 24시간 보관

# 자동 downsample rule
> TS.CREATERULE temperature:tlv temperature:tlv:1min AGGREGATION avg 60000
OK

이제 raw 시리즈에 추가되는 모든 sample 이 1분 단위로 자동 평균되어 destination 에 누적돼요. raw 는 짧게 보관하고 집계는 오래 두는 — 메트릭 인프라의 표준 패턴입니다.

Labels — Multi-dimensional 모델

Prometheus·InfluxDB 가 쓰는 시리즈 + 라벨 모델이에요.

> TS.CREATE cpu:usage LABELS region us-east host web1 metric cpu
> TS.CREATE cpu:usage:web2 LABELS region us-east host web2 metric cpu
> TS.CREATE cpu:usage:db1 LABELS region us-east host db1 metric cpu

# us-east 의 모든 cpu
> TS.MRANGE - + FILTER region=us-east metric=cpu

키 이름으로만 구분하던 옛 패턴에서 라벨로 다차원 쿼리하는 방식으로 바뀌었어요. 운영 모니터링 표준입니다.

Retention — 자동 만료

> TS.CREATE temperature:tlv RETENTION 86400000     # 24시간

24시간 이상 된 sample 은 자동으로 삭제돼요. 무한 누적을 막아줍니다.

런타임에 바꿀 수도 있어요:

> TS.ALTER temperature:tlv RETENTION 172800000     # 48시간으로

Compaction Rules — Downsampling

위에서 본 TS.CREATERULE 패턴이에요. raw 는 짧게, 집계는 오래 보관하는 인프라 모니터링의 표준 흐름입니다.

raw (1초 단위, 1시간 보관)
  ↓ TS.CREATERULE AGGREGATION avg 60000
1분 평균 (24시간 보관)
  ↓ TS.CREATERULE AGGREGATION avg 3600000
1시간 평균 (30일 보관)

3단계로 다양한 zoom level 의 시계열을 동시에 제공할 수 있어요.

Redis Time Series vs 시계열 전문 DB

항목 Redis TS InfluxDB Prometheus TimescaleDB
모델 인메모리 디스크 인메모리 + 디스크 PG 위
지연 시간 μs ms ms ms
처리량 매우 높음 매우 높음 매우 높음 높음
데이터 크기 메모리 한계 TB+ 수 GB TB+
쿼리 언어 Redis 명령 Flux PromQL SQL
집계 풍부함 중간 풍부 풍부 SQL 풍부
Pull vs Push Push Push Pull Push
운영 복잡도 낮음 중간 중간 중간
통합 인프라 Redis 한 인스턴스 별도 별도 PG 와 동일

선택 가이드

  • 이미 Redis 있음 + 작은~중간 규모 + 단순 시계열Redis Time Series
  • 거대 시계열 + 풍부한 쿼리InfluxDB / TimescaleDB
  • 인프라 모니터링 + Push 모델Prometheus
  • SQL 기반 분석 + 기존 PG 환경TimescaleDB

대부분의 작은~중간 규모 메트릭이나 애플리케이션 비즈니스 지표는 Redis TS 로 충분해요. 진짜 모니터링 인프라(수만 대 서버)는 Prometheus 에 장기 저장소를 따로 붙이는 구성이 일반적입니다.

Gorilla 압축 — 핵심 효율

기본 ENCODING COMPRESSEDGorilla 압축(Facebook 시계열 압축)이에요.

원리는 세 가지로 갈라져요:

  • delta-of-delta 인코딩 — 연속된 timestamp 차이의 차이만 저장
  • XOR 인코딩 — 연속된 값의 변화만 저장
  • bit-packing — 가능한 적은 비트로 묶기

결과는 원본 16바이트 sample 을 평균 1~3바이트로 줄이는 거예요. 수십배 메모리 절약 입니다.

여기서 시험 함정이 하나 있어요 — UNCOMPRESSED 옵션은 쓰기 성능을 약간 빠르게 하지만 메모리 사용이 폭증해요. 고빈도 시계열에서는 무조건 COMPRESSED 입니다.

Spring Boot 통합

Spring Data Redis 에는 Time Series 1급 API 가 없어요. raw 명령을 직접 보내거나 redis-modules-java 라이브러리를 씁니다.

@Autowired
private RedisTemplate<String, String> redisTemplate;

public Long addSample(String key, double value) {
    return (Long) redisTemplate.execute(
        (RedisCallback<Object>) connection ->
            connection.execute("TS.ADD", key.getBytes(), "*".getBytes(),
                              String.valueOf(value).getBytes())
    );
}

한계·실무 함정

1. 메모리 한계

수 TB 시계열은 Redis 에 부적합해요. retention 과 downsampling 으로 작게 유지하거나, 전문 시계열 DB 로 넘어가야 합니다.

2. Cluster 환경 — 시리즈 분산 X

각 시리즈는 한 슬롯에만 살아 있어요. 하나의 시리즈가 매우 큰 경우 그 노드만 부하를 받습니다. 라벨별로 키 prefix 를 분산하는 패턴으로 풀어요.

3. UNCOMPRESSED 메모리 폭증

위에서 강조한 그대로예요. COMPRESSED 가 기본이고 거의 모든 경우 정답입니다.

4. Compaction 자동 X

TS.CREATERULE 을 박지 않으면 자동 downsampling 은 안 돌아가요. 직접 설정해야 합니다.

5. 시계열 백필 (역방향 추가) 제약

기본은 timestamp 가 단조 증가하는 걸 전제로 해요. 과거 시점 sample 을 추가하려면 DUPLICATE_POLICY(중복 정책) 설정이 필요합니다.

시험 직전 한 번 더 — Time Series 함정 압축 노트

  • Time Series = (timestamp, value) sample 시퀀스 native 모듈
  • 핵심 명령 = TS.CREATE·TS.ADD·TS.MADD·TS.RANGE·TS.MRANGE·TS.GET·TS.MGET·TS.CREATERULE·TS.INFO
  • TS.ADD * value = 현재 시간 자동
  • TS.MADD = 여러 시리즈 한 호출
  • TS.RANGE - + AGGREGATION avg 300000 = 5분 단위 평균
  • 집계 함수 = avg·min·max·sum·count·first·last·range·std·var
  • Labels = Prometheus 스타일 key-value (LABELS region us-east host web1)
  • TS.MRANGE FILTER label=value = 라벨 필터 다차원 쿼리
  • RETENTION <ms> = 자동 만료 (0 = 무제한)
  • TS.CREATERULE source dest AGGREGATION avg 60000 = 자동 downsampling
  • raw + 1분 + 1시간 다단계 compaction = 메트릭 표준
  • Gorilla 압축 (Facebook) = delta-of-delta + XOR + bit-packing
  • 원본 16바이트 → 평균 1~3바이트 = 수십배 절약
  • UNCOMPRESSED = 쓰기 약간 빠름, 메모리 폭증 → 거의 사용 안 함
  • vs InfluxDB = 거대 시계열 + 풍부한 쿼리는 InfluxDB
  • vs Prometheus = Pull 모델 + 인프라 모니터링은 Prometheus
  • vs TimescaleDB = SQL 분석 + 기존 PG 환경은 TimescaleDB
  • 선택 — Redis 있음 + 작은~중간 = Redis TS
  • 함정 — 메모리 한계, retention/compaction 필수
  • 함정 — Cluster 환경 한 시리즈 = 한 슬롯 부하
  • 함정 — UNCOMPRESSED 메모리 폭증
  • 함정 — Compaction 자동 X, CREATERULE 박기
  • Spring 통합 = raw 명령 또는 redis-modules-java

공식 문서: Redis Time Series 에서 자세한 명령어 사양을 확인할 수 있어요.

시리즈 다른 편 (앞뒤 글 모음)

이전 글:

다음 글:

※ 이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다.

답글 남기기

error: Content is protected !!