← 학습 카테고리

Learn

Kafka

84개 모듈 · 현재 45번째

Kafka 모듈 45/84 kafka-learn-45

Tiered Storage — 로컬과 원격 계층으로 나눠 저장하기

Apache Kafka Tiered Storage(KIP-405) 공식 문서 및 Confluent Schema Registry 호환성 모드 문서 종합 (웹 리서치, 2026) — Apache Kafka 공식 문서(kafka.apache.org/41/operations/tiered-storage) + Confluent 공식 문서(schema-evolution) Apache Kafka 공식 문서 operations/tiered-storage (KIP-405, Kafka 3.9부터 프로덕션 레디)

이 모듈을 다 읽으면

  • Tiered Storage가 로컬 디스크와 원격 저장소를 어떤 기준으로 나누는지 설명할 수 있다
  • local.retention과 retention(전체 보존)의 관계를 구분할 수 있다
  • Tiered Storage의 주요 제약사항을 판단할 수 있다

kafka-learn-11에서 다룬 세그먼트 기반 물리 저장을 전제로, 오래된 세그먼트를 저비용 원격 저장소로 자동 오프로드하는 Tiered Storage(KIP-405, Kafka 3.9부터 프로덕션 레디)의 동작 원리와 제약을 정리한다.

왜 필요한가 — 대부분의 읽기는 '최신 데이터'만 본다

Kafka 데이터는 대부분 스트리밍 방식으로 '꼬리(tail) 읽기'된다 — 방금 들어온 최신 레코드를 계속 따라 읽는 패턴이 압도적으로 많고, 이런 읽기는 OS 페이지 캐시에서 바로 서빙된다. 반면 오래된 데이터(며칠~몇 달 전)는 훨씬 드물게, 주로 재처리나 감사 목적으로만 접근된다. Tiered Storage는 이 비대칭성을 이용해, 접근 빈도가 높은 최신 데이터는 브로커 로컬 디스크(hot tier)에 남기고 오래된 세그먼트는 S3/HDFS 같은 저비용 원격 저장소(cold tier)로 자동 이관한다 — 브로커 로컬 디스크 용량과 무관하게 사실상 무제한에 가까운 보존 기간을 값싸게 확보할 수 있다.

핵심 포인트

  • 대부분의 읽기는 최신 데이터(꼬리 읽기, 페이지 캐시로 서빙)에 몰리고 오래된 데이터는 드물게 접근된다는 비대칭성이 전제
  • 이 비대칭성을 이용해 최신 데이터는 로컬(hot), 오래된 세그먼트는 저비용 원격(cold)으로 자동 이관해 사실상 무제한급 보존을 값싸게 확보한다

핵심 설정 — local.retention vs retention

브로커 전체 설정으로 remote.log.storage.system.enable=true를 켜야 클러스터 차원에서 기능이 활성화되고(RemoteStorageManager 구현체를 별도로 지정해야 하며, Kafka 자체는 구현체를 기본 제공하지 않는다), 토픽 단위로는 remote.storage.enable=true로 개별 토픽에 적용한다. 여기서 헷갈리기 쉬운 두 종류의 보존 설정이 있다: local.retention.ms/bytes는 세그먼트가 '로컬 디스크에' 남아있을 수 있는 기간/크기이고(이 시점이 지나면 원격으로 업로드된 뒤 로컬 사본은 삭제됨), retention.ms/bytes는 로컬+원격을 합친 '전체' 데이터의 보존 기간/크기다. 즉 local.retention은 항상 retention보다 작거나 같아야 하며, 그 차이만큼이 '원격에만 남아있는' 데이터 구간이 된다.

핵심 포인트

  • local.retention.ms/bytes = 로컬 디스크에 남는 기간/크기(지나면 원격 업로드 후 로컬 삭제), retention.ms/bytes = 로컬+원격 합산 전체 보존
  • local.retention ≤ retention이어야 하고, 그 차이가 '원격에만 있는' 데이터 구간이다

컨슈머 입장에서는 투명하다 — 그리고 알아둬야 할 제약

세그먼트가 로컬에서 원격으로 이관되어도 컨슈머는 이를 신경 쓸 필요가 없다 — RemoteLogMetadataManager가 어느 오프셋 범위가 어느 저장소(로컬/원격)에 있는지 추적하고, 컨슈머가 원격에만 남은 오래된 오프셋을 요청하면 브로커가 그 요청을 대신 원격 저장소로 라우팅해 투명하게 데이터를 가져다준다. 다만 알아둬야 할 제약이 여럿 있다: 압축(compact) 토픽은 지원하지 않는다, 클러스터 전체에서 기능을 끄려면 먼저 모든 토픽에서 개별적으로 비활성화해야 한다, 원격 저장소로부터의 fetch는 요청당 파티션 1개로 제한돼 있어(처리량 병목이 될 수 있음), 2.8.0 이전에 만들어져 producer snapshot 파일이 없는 세그먼트와는 호환되지 않는다.

핵심 포인트

  • 컨슈머는 데이터가 로컬/원격 어디 있는지 신경쓸 필요 없이 투명하게 읽는다(RemoteLogMetadataManager가 추적)
  • 제약: 압축(compact) 토픽 미지원, 클러스터 전체 비활성화 전 토픽별 비활성화 선행 필요, 원격 fetch는 요청당 파티션 1개 제한(처리량 병목 가능), 2.8.0 이전 세그먼트(producer snapshot 없음)와 비호환