백엔드 데이터 인프라 106편. Kafka Tiered Storage — local SSD + remote S3/HDFS 2-tier 모델. RemoteStorageManager·RemoteLogMetadataManager·local.retention vs retention·비용 1/10 절감·운영 가이드까지 풀어쓴 학습 노트.
이 글은 백엔드 데이터 인프라 시리즈 130편 중 106편이에요. 105편 에서 KRaft 를 잡았다면, 이번 106편은 Tiered Storage — Kafka 의 데이터를 두 단계 (local + remote) 로 나눠 저장하는 기능이고, 비용·retention 양쪽의 게임 체인저예요.
Tiered Storage가 어렵게 느껴지는 이유
이전 Kafka 는 모든 데이터를 broker 로컬 디스크에 두는 구조였어요. 수년치 데이터를 보존하려 들면 디스크가 폭증하거나, 클러스터를 키우는 비용이 비현실적인 수준이 됐죠.
첫 번째 걸림돌은 cold data 문제예요. 84편에서 본 것처럼 대부분의 read 는 tail (최근 데이터) 에 몰리고 오래된 데이터는 가끔 읽히는데, 그 오래된 데이터도 비싼 broker SSD 자리를 똑같이 차지하고 있다는 거죠.
두 번째 걸림돌은 새 아키텍처 개념이에요. RemoteStorageManager (remote 저장 lifecycle 인터페이스) · RemoteLogMetadataManager (remote segment 메타데이터 인터페이스) 같은 새로운 plug-in interface 가 등장하거든요.
이 글에서는 Tiered Storage 의 의의·구조·설정·비용·운영까지 한 번에 짚어요.
핵심 모델 — 2-tier Storage
Topic "events" (RF=3)
Hot Data (최근, tail reads)
↓ local SSD
[Broker 1] [Broker 2] [Broker 3] ← 빠른 SSD
Cold Data (오래된, 가끔 backfill)
↓ remote (S3·HDFS·blob storage)
┌────────────────────────────────┐
│ S3 bucket: kafka-events/... │
└────────────────────────────────┘
Local Tier 는 broker 로컬 디스크 그대로고, Remote Tier 는 S3 · HDFS (Hadoop 분산 파일시스템) · 외부 storage 처럼 외부 저장소예요. RF (Replication Factor, 복제본 수) 는 local tier 에만 적용되고, remote 쪽은 storage 자체의 내구성에 맡기는 모델이고요. 오래된 segment 가 자동으로 remote tier 로 옮겨가면서 로컬 디스크에는 최근 데이터만 남게 되는 구조예요.
효과 — 비용 1/10
시나리오 (대략)
10 broker cluster, 30일 retention, 10TB 데이터:
| 모델 | 로컬 SSD | 비고 |
|---|---|---|
| Local-only | 10 TB × 3 (RF) ÷ 10 broker = 3 TB/broker | 큰 SSD 필요 |
| Tiered (3일 local, 27일 remote) | 0.3 TB/broker + S3 9 TB | SSD 1/10 + 저렴한 S3 |
비용은 SSD 1TB 가 클라우드 instance 포함 월 $200 수준이고, S3 1TB 는 Standard 기준 월 $23 정도예요. 단순 계산만 해도 10배쯤 차이가 나니까, retention 이 큰 환경에서는 이게 게임 체인저가 되는 거죠.
핵심 인터페이스
RemoteStorageManager
public interface RemoteStorageManager {
void copyLogSegmentData(...); // local → remote
InputStream fetchLogSegment(...); // remote → consumer
void deleteLogSegmentData(...); // remote 삭제
// ...
}
remote storage 의 lifecycle 을 관리하는 인터페이스고, AWS S3 · HDFS · Azure Blob 처럼 백엔드마다 각자 구현체를 붙이게 돼 있어요.
RemoteLogMetadataManager
public interface RemoteLogMetadataManager {
void addRemoteLogSegmentMetadata(...);
Iterator<RemoteLogSegmentMetadata> listRemoteLogSegments(...);
// ...
}
remote segment 의 metadata 를 관리하는 쪽이고, 기본 구현은 Kafka internal topic (__remote_log_metadata) 을 그대로 활용해요.
설정
Broker 측 (cluster-wide 활성)
# 기본 활성
remote.log.storage.system.enable=true
# RemoteStorageManager 구현체
remote.log.storage.manager.class.name=org.apache.kafka.server.log.remote.storage.LocalTieredStorage
remote.log.storage.manager.class.path=...
# RemoteLogMetadataManager (기본 = internal topic)
remote.log.metadata.manager.listener.name=PLAINTEXT
Topic 측 (per-topic 활성)
$ kafka-topics.sh --bootstrap-server localhost:9092 \
--alter --topic events \
--config remote.storage.enable=true \
--config local.retention.ms=259200000 \
--config retention.ms=2592000000
설정에서 핵심은 세 개예요. remote.storage.enable=true 가 이 topic 에 tiered storage 를 켜는 스위치고, local.retention.ms 는 local 에 남길 기간 (예시는 3일), retention.ms 는 전체 보존 기간 (예시는 30일) 이라 그 차이인 27일이 remote 에 남는 셈이에요.
여기서 시험 함정이 하나 있어요 — local.retention.ms 와 retention.ms 의 관계예요. local.retention.ms 는 local 만의 retention 이고 이 시점이 지나면 remote 로 넘어가요. retention.ms 는 local 과 remote 를 합친 전체 retention 이고요. local.retention.ms 를 따로 명시하지 않으면 retention.ms 와 같은 값으로 잡혀서 결국 local-only 처럼 동작해요.
동작 흐름
Write (producer)
Producer → Broker → local segment 에 write
(변화 없음, 기존과 동일)
Local → Remote 이동
local.retention.ms 초과 → 백그라운드 thread 가 segment 통째로 S3 upload
→ metadata 를 RemoteLogMetadataManager 에 등록
→ local segment 삭제
Read (consumer)
Consumer.poll()
├─ 최근 데이터 (local) → broker page cache·디스크 (μs~ms)
└─ 오래된 데이터 (remote) → S3 fetch (수십~수백 ms)
consumer 쪽에서는 API 가 똑같아서 투명하게 보이고, 차이는 응답 시간에만 드러나요.
Quick Start Example — LocalTieredStorage
테스트용 LocalTieredStorage 는 로컬 디렉토리를 remote 인 척 흉내내는 구현체예요.
# 1. test jar 빌드
$ ./gradlew clean :storage:testJar
# 2. broker 설정
remote.log.storage.system.enable=true
remote.log.storage.manager.class.name=\
org.apache.kafka.server.log.remote.storage.LocalTieredStorage
remote.log.storage.manager.impl.prefix=rsm.config.
rsm.config.dir=/tmp/kafka-remote-storage
# 3. topic 생성·활성
$ kafka-topics.sh --create --topic test-tiered \
--partitions 1 --replication-factor 1 \
--config remote.storage.enable=true \
--config local.retention.ms=10000 \
--config segment.ms=5000
# 4. 메시지 produce·기다림·consume
# 5. /tmp/kafka-remote-storage/ 안 segment 확인
운영 환경 — S3 기반
AWS MSK Tiered Storage
AWS MSK (Managed Streaming for Kafka) 는 기본으로 지원해서 콘솔에서 토글만 켜면 끝이에요.
MSK Cluster → Topic → Configuration → Tiered Storage ✓
내부적으로는 S3 를 쓰고 운영은 MSK 가 알아서 해줘요.
Confluent Tiered Storage
Confluent Platform · Cloud 는 S3 · GCS · Azure 용 RemoteStorageManager 를 공식으로 제공하니까, 설정만 명시해서 붙이면 돼요.
Self-Hosted + S3
Apache Kafka 만으로 S3 백엔드를 쓰려면 RemoteStorageManager 를 직접 구현해야 해요. Apache 가 공식 구현을 주지 않아서, 보통은 AIVEN (Aiven 사가 공개한 오픈소스 구현) 같은 third-party 구현을 가져다 쓰죠.
비용·성능 Trade-off
비용
Local SSD (broker EBS gp3) ≈ $80/TB/월
S3 Standard ≈ $23/TB/월
S3 Glacier Instant Retrieval ≈ $4/TB/월
EBS gp3 (AWS 범용 SSD 볼륨 타입) 기준으로 봐도 S3 Standard 와 한참 차이가 나고, S3 Glacier Instant Retrieval (즉시 인출 가능한 저비용 등급) 까지 내려가면 단가는 매우 저렴해요. 대신 Glacier IR 은 fetch 가 살짝 느려진다는 트레이드가 따라붙어요.
성능
| Tier | Read latency | 자주 보는 자리 |
|---|---|---|
| Local (page cache) | μs | Tail reads (대부분) |
| Local (disk) | ms | Recent backfill |
| Remote (S3) | 수십~수백 ms | Old backfill, replay |
| Remote (Glacier IR) | 수백 ms | 매우 오래된 분석 |
대부분의 consumer 는 tail read (최근 데이터 따라잡기) 라서 체감 영향은 거의 없고, 오래된 데이터를 다룰 때만 느려져요.
활용 사례
1. Compliance·법적 보존
금융·의료처럼 7년·10년 보존이 강제되는 도메인에서는 Tiered Storage 없이는 비용이 비현실적인 수준이에요.
2. ML 학습 데이터
오래된 데이터를 주기적으로 batch (한꺼번에) 로 가져와 모델을 학습시키는 경우, local-only 였다면 그 모든 데이터를 broker SSD 가 떠안아야 해요.
3. Event Sourcing — 전체 이벤트 보존
도메인 이벤트를 영구 보존해두고 가끔 상태를 재계산하는 패턴에 Tiered Storage 가 정확히 들어맞아요.
4. CDC + 데이터 아카이브
CDC (Change Data Capture, DB 변경 캡처) → Kafka 흐름에서 오래된 메시지까지 audit · debugging 용으로 남겨두는 구조에도 잘 맞고요.
한계·실무 함정
1. Compaction 지원
Tiered Storage 와 log compaction 의 호환성은 Kafka 3.6+ 부터 일부만 지원돼요. 쓰기 전에 정확한 호환 범위를 확인해야 해요.
2. RemoteStorageManager 구현체 선택
Apache Kafka 공식 구현은 LocalTieredStorage 가 전부고 이건 테스트용이에요. 운영은 AWS MSK · Confluent · AIVEN 같은 third-party 중에서 골라야 해요.
3. Internal Topic 의 metadata 부담
__remote_log_metadata 토픽이 모든 remote segment 메타데이터를 떠안기 때문에, cluster 규모가 매우 커지면 이 토픽 자체가 부담이 돼요. 그땐 별도 RemoteLogMetadataManager 구현을 검토해야 하고요.
4. Read latency 폭증
오래된 데이터 read 가 갑자기 몰리면 S3 fetch 가 같이 폭증하고 비용도 같이 튀어요. 필요하면 throttle 을 걸어 통제해요.
5. S3 retention 정책 일관성
Kafka 의 retention 과 S3 lifecycle policy 가 어긋나면 데이터가 사라지는 사고가 나요. 그래서 retention 은 Kafka 한쪽에서만 관리하는 게 권장이에요.
6. 모니터링 메트릭
RemoteCopyBytesPerSec · RemoteFetchBytesPerSec · RemoteCopyLagBytes 같은 새 메트릭이 생기니까, 운영 모니터링 대시보드에도 같이 넣어둬야 해요.
시험 직전 한 번 더 — Kafka Tiered Storage 함정 압축 노트
- Tiered Storage = local SSD + remote (S3/HDFS/Blob) 2-tier
- KIP-405 = Kafka 3.6+ 도입
- 효과 = 비용 ~10배 절감 (거대 retention 환경)
- Hot Data = local (tail reads, μs)
- Cold Data = remote (backfill, 수십~수백 ms)
- RemoteStorageManager = remote storage lifecycle 인터페이스
- RemoteLogMetadataManager = remote segment metadata (기본 = internal topic
__remote_log_metadata) - Broker 설정 =
remote.log.storage.system.enable=true+ manager class - Topic 설정 =
remote.storage.enable=true+local.retention.ms+retention.ms local.retention.ms= local 만 기간retention.ms= 전체 보존 (local + remote)- 명시 안 하면 = local 만 (기본 동작)
- 동작 — Write 동일, local 만료 시 remote 자동 이동, Consumer 투명
- AWS MSK Tiered Storage = 콘솔 enable
- Confluent = 공식 RemoteStorageManager (S3·GCS·Azure)
- Self-hosted + S3 = third-party (AIVEN) 또는 직접 구현
- 비용 — Local SSD $80/TB vs S3 Standard $23/TB vs Glacier IR $4/TB
- 성능 — Local μs / Local disk ms / S3 수십~수백 ms / Glacier 수백 ms
- 대부분 consumer = tail read 라 영향 최소
- 활용 = compliance·법적 보존·ML 학습·event sourcing·CDC archive
- 함정 — log compaction 호환성 (3.6+ 일부)
- 함정 — RemoteStorageManager 구현체 선택
- 함정 — internal metadata topic 부담
- 함정 — old data read 폭증 = S3 비용
- 함정 — S3 lifecycle policy 와 Kafka retention 충돌
- 모니터링 =
RemoteCopyBytesPerSec·RemoteFetchBytesPerSec·RemoteCopyLagBytes
공식 문서: Kafka Tiered Storage 에서 자세한 사양과 설정을 확인할 수 있어요.
시리즈 다른 편 (앞뒤 글 모음)
이전 글:
- 101편 — Kafka Multi-tenancy (Quota · Naming · ACL 분리)
- 102편 — Kafka 다중 데이터센터 (Stretched · Local + Mirror)
- 103편 — Kafka Geo-Replication (MirrorMaker 2)
- 104편 — Kafka Hardware · OS (CPU·메모리·디스크·튜닝)
- 105편 — Kafka KRaft (Zookeeper 의 후속 · Quorum 운영)
다음 글: