Apache Iceberg 테이블에 스트리밍 데이터 삽입 방법
출처: Dev.to
이 글은 15부작 Apache Iceberg 마스터클래스의 13번째 파트입니다. 12부에서는 Python과 MPP 엔진을 다뤘습니다. 이번 글에서는 Iceberg 테이블에 스트리밍 데이터를 넣는 세 가지 주요 접근 방식과 각각이 초래하는 운영상의 트레이드오프를 살펴봅니다.
Iceberg는 배치 분석을 위해 설계되었지만, 실제 프로덕션 데이터는 대부분 지속적으로 들어옵니다. 스트리밍 인제스트는 일정 간격으로 데이터를 Iceberg 테이블에 커밋함으로써 이 격차를 메워줍니다. 문제는 빈번한 커밋이 작은 파일 문제를 야기한다는 점이며, 데이터 신선도와 테이블 건강 사이의 균형을 관리하는 것이 스트리밍을 Iceberg에 적용할 때 가장 큰 고민입니다.
목차
- 테이블 포맷이란 무엇이며 왜 필요했는가?
- 현재 테이블 포맷의 메타데이터 구조
- 성능과 Apache Iceberg의 메타데이터
- 파티션 진화에 대한 기술적 깊이 파고들기
- 숨겨진 파티셔닝에 대한 기술적 깊이 파고들기
- Apache Iceberg 테이블에 쓰기
- 레이크하우스 카탈로그란?
- 임베디드 카탈로그: S3 테이블 및 MinIO AI 스토어
- Iceberg 테이블 스토리지가 시간이 지남에 따라 악화되는 이유
- Apache Iceberg 테이블 유지보수
- Apache Iceberg 메타데이터 테이블
- Python과 MPP 엔진으로 Iceberg 사용하기
- Apache Iceberg 테이블에 스트리밍 데이터 넣기
- Dremio Cloud와 함께하는 Iceberg 실습
- Apache Iceberg로 마이그레이션하기
Spark Structured Streaming
Spark Structured Streaming은 마이크로배치 방식으로 데이터를 처리하고, 설정 가능한 간격마다 Iceberg에 커밋합니다.
df = spark.readStream.format("kafka") \
.option("subscribe", "events") \
.load()
df.writeStream.format("iceberg") \
.outputMode("append") \
.option("checkpointLocation", "s3://checkpoint/events") \
.trigger(processingTime="60 seconds") \
.toTable("analytics.events")
각 트리거는 누적된 데이터를 하나의 Iceberg 커밋으로 만들며, 60초 트리거라면 하루에 1,440개의 커밋이 생성되고 각각은 소수의 파일을 추가합니다.
- 지연 시간: 초~분 (트리거 간격에 따라 조정 가능)
- 소형 파일 영향: 보통. 트리거 간격을 늘리면 파일 수가 줄고 파일 크기는 커집니다.
- 추천 대상: 이미 Spark를 배치 처리에 사용하고 있으며, 거의 실시간에 가까운 인제스트를 추가하고 싶은 팀
Flink
Flink는 이벤트를 지속적으로 처리하고 체크포인트 간격마다 Iceberg에 커밋합니다.
-- Flink SQL
INSERT INTO iceberg_catalog.analytics.events
SELECT event_id, event_time, payload
FROM kafka_source
Flink의 체크포인트 메커니즘이 커밋 빈도를 결정합니다. 예를 들어 30초 체크포인트 간격이면 30초마다 현재까지 모인 데이터를 커밋합니다.
- Exactly‑once 보장: 체크포인트 메커니즘을 통해 Iceberg에 정확히 한 번만 전달됩니다. 작업이 중단되면 마지막 체크포인트부터 복구하고 아직 커밋되지 않은 데이터를 다시 재생하므로 중복 레코드나 데이터 손실이 없습니다. 이는 금융·거래 파이프라인에 필수적입니다.
- 파티션된 쓰기: Flink는 파티션 변환을 기반으로 이벤트를 동적으로 라우팅할 수 있습니다. Iceberg의 숨겨진 파티셔닝과 결합하면 스트리밍 애플리케이션에 별도 로직을 넣지 않아도 올바른 파티션 디렉터리로 자동 배치됩니다.
- Upsert 및 CDC: Flink는 changelog 스트림(삽입, 업데이트, 삭제)을 지원하며, 이를 Iceberg에 equality delete와 데이터 파일 형태로 기록할 수 있습니다. 따라서 DB 트랜잭션 로그를 직접 Iceberg 테이블에 스트리밍해 거의 실시간 복제본을 유지하는 CDC 패턴이 구현됩니다.
- 지연 시간: 초 (체크포인트 간격에 의존)
- 소형 파일 영향: 높음. 체크포인트가 자주 발생하면 작은 파일이 많이 생성됩니다.
- 추천 대상: 가장 낮은 지연 시간과 Exactly‑once 보장, CDC 지원이 필요한 팀
Iceberg Sink Connector (Kafka Connect)
Iceberg Sink Connector는 Kafka 토픽에서 직접 데이터를 읽어 Iceberg 테이블에 기록합니다.
{
"name": "iceberg-sink",
"config": {
"connector.class": "org.apache.iceberg.connect.IcebergSinkConnector",
"topics": "events",
"iceberg.catalog.type": "rest",
"iceberg.catalog.uri": "https://catalog.example.com",
"iceberg.tables": "analytics.events"
}
}
- 지연 시간: 분 (Kafka Connect가 레코드를 배치 처리한 뒤 커밋)
- 소형 파일 영향: Spark/Flink보다 낮음 (커밋 빈도가 적음)
- 추천 대상: 기존에 Kafka 인프라가 구축돼 있고, 관리형 커넥터 방식으로 Iceberg를 도입하고 싶은 조직
Apache Iceberg Sink Connector 소개
커뮤니티가 유지보수하는 이 커넥터는 Kafka Schema Registry와 연동해 스키마 진화를 지원하고, 테이블 자동 생성 및 파티션 라우팅 기능을 제공합니다. 레코드를 메모리 버퍼에 모았다가 설정된 배치 간격으로 Iceberg에 커밋합니다.
- 운영 단순성: Kafka Connect는 관리형 프레임워크입니다. 커넥터 설정만 배포하면 Connect가 스케일링, 오프셋 관리, 장애 복구 등을 자동으로 처리합니다. 별도 애플리케이션 코드를 작성·유지보수할 필요가 없으며, 이미 다른 싱크(데이터베이스, 검색 인덱스 등)를 위해 Connect를 사용 중이라면 Iceberg 싱크 추가가 매우 간단합니다.
모든 스트리밍 방식이 공유하는 근본적인 문제
빈번한 커밋 → 작은 파일
이를 해결하려면 스트리밍 인제스트와 적극적인 컴팩션을 결합해야 합니다.
전형적인 프로덕션 패턴
- Flink 또는 Spark로 60초 커밋 간격으로 스트리밍 ingest
- 매시간 컴팩션을 실행해 지난 한 시간 동안 생성된 작은 파일들을 최적 크기의 파일로 병합
- 매일 스냅샷을 만료시켜 누적된 스냅샷 메타데이터를 정리
Dremio의 자동 테이블 최적화는 Open Catalog로 관리되는 테이블에 대해 이 컴팩션을 자동으로 수행합니다. AWS S3 Tables 역시 스트리밍 워크로드에 대한 내장 컴팩션 기능을 제공합니다.
핵심 인사이트
항상 초단위 지연이 필요한 것은 아닙니다. 대부분의 대시보드는 5~15분마다 새로 고침됩니다. 소비자가 5분 정도의 데이터 신선도를 감당할 수 있다면, 5분 트리거 간격을 사용해 작은 파일을 90% 정도 줄이고 컴팩션 오버헤드를 크게 낮출 수 있습니다.
프로덕션 스트리밍‑to‑Iceberg 파이프라인 구성 요소 (4가지)
- 메시지 큐 (Kafka, Kinesis, Pulsar): 소스 시스템에서 이벤트를 버퍼링
- 스트림 프로세서 (Flink, Spark Streaming): 변환 후 Iceberg에 기록
- 컴팩션 서비스 (Dremio 자동 최적화, Spark 스케줄러 등): 정기적으로 작은 파일을 병합
- 모니터링 (메타데이터 테이블): 파일 수·크기·커밋 빈도 추적
가장 흔한 실수
스트림 프로세서만 배포하고 컴팩션 서비스를 놓치는 경우가 많습니다. 컴팩션이 없으면 쿼리 성능이 며칠 만에 급격히 저하됩니다. 두 컴포넌트를 반드시 함께 운영하세요.
배포 후 일일 모니터링 지표 (메타데이터 테이블 활용)
- 커밋 빈도: 시간당 몇 개의 스냅샷이 생성되는가?
- 평균 파일 크기: 작은 파일 문제가 악화되고 있는가?
- 컴팩션 지연: 컴팩션 작업이 쓰기 속도를 따라잡고 있는가?
- 엔드‑투‑엔드 지연: 이벤트 발생 시점부터 Iceberg에서 쿼리 가능해질 때까지 걸리는 시간
잘 튜닝된 스트리밍 파이프라인은 15분마다 커밋하고, 커밋당 32128 MB 파일을 생성하며, 30~60분마다 컴팩션을 실행해 256 MB 목표 파일 크기로 합칩니다.
다음 14부에서는 Dremio Cloud에서 Iceberg을 직접 다루는 실습을 제공합니다.
참고 서적 및 강좌
- Architecting the Apache Iceberg Lakehouse – Alex Merced (Manning)
- Lakehouses with Apache Iceberg: Agentic Hands‑on – Alex Merced
- Constructing Context: Semantics, Agents, and Embeddings – Alex Merced
- Apache Iceberg & Agentic AI: Connecting Structured Data – Alex Merced
- Open Source Lakehouse: Architecting Analytical Systems – Alex Merced
- FREE – Apache Iceberg: The Definitive Guide
- FREE – Apache Polaris: The Definitive Guide
- FREE – Agentic AI for Dummies
- FREE – Leverage Federation, The Semantic Layer and the Lakehouse for Agentic AI
- FREE with Survey – Understanding and Getting Hands‑on with Apache Iceberg in 100 Pages