백엔드 데이터 인프라 76편. Redis Time Series 모듈 — 시계열 데이터 native 지원. TS.CREATE·TS.ADD·TS.RANGE·TS.MRANGE·TS.CREATERULE 명령어와 Prometheus 스타일 labels, retention/compaction rule, InfluxDB·TimescaleDB·Prometheus 와의 비교까지 풀어쓴 학습 노트.
이 글은 백엔드 데이터 인프라 시리즈 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 COMPRESSED 는 Gorilla 압축(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 에서 자세한 명령어 사양을 확인할 수 있어요.
시리즈 다른 편 (앞뒤 글 모음)
이전 글:
- 71편 — Redis TLS (전송 암호화 · mTLS)
- 72편 — Redis 메모리 최적화 (Encoding · Hash 압축 · Fragmentation)
- 73편 — Spring Data Redis (RedisTemplate · @Cacheable)
- 74편 — RedisJSON (JSON.SET · JSONPath · PG JSONB 비교)
- 75편 — RediSearch (FT.CREATE · FT.SEARCH · FT.AGGREGATE)
다음 글: