Iceberg는 대규모 분석 데이터를 위한 오픈 테이블 포맷이다. 원래 Netflix에서 시작되어 현재는 Apache Software Foundation에서 관리하고 있으며, 데이터 레이크에 저장된 파일들을 효율적으로 관리하고 분석 성능을 높이기 위해 만들어졌다.
HDFS + Hive 메타스토어 방식으로 데이터를 관리하는 방식에는 아래와 같은 한계가 있다.
Iceberg는 이 한계 극복을 위한 아래와 같은 기능을 가진다.
| 항목 | 설명 |
|---|---|
| 종류 | 오픈 테이블 포맷 (Apache Iceberg) |
| 목적 | 대규모 분석 데이터를 안정적이고 효율적으로 관리 |
| 지원 파일 포맷 | Parquet, ORC, Avro 등 |
| 저장소 | S3, HDFS, Azure, GCS 등 다양한 오브젝트 스토리지 |
| 주요 엔진 연동 | Spark, Trino, Flink, Hive, Presto 등 |
🏳️🌈 [궁금한점]
구조 요약
Iceberg Table
├── Metadata (metadata.json, snapshot files)
│ └── 테이블 구조, 스냅샷 이력 등 저장
├── Manifest Lists
│ └── 어떤 매니페스트 파일을 사용할지 정의
├── Manifest Files
│ └── 실제 데이터 파일 경로, 파티션 정보 등
└── Data Files (Parquet 등)
└── 실제 데이터 저장
오픈 테이블 포맷(Open Table Format)은 데이터 레이크에서 대규모 데이터를 표 형태(테이블)로 구조화하여 저장하고 관리하기 위한 표준 방식이다. 즉, 파일 시스템에 저장된 데이터들을 마치 데이터베이스 테이블처럼 다룰 수 있게 해주는 규칙/포맷이다. 데이터 레이크에 저장된 파일(Parquet, ORC 등)을 테이블처럼 관리할 수 있도록 메타데이터와 동작 방식을 표준화한다.
데이터 레이크에 데이터를 저장하면, 보통은 파일 단위(예: .parquet)로만 존재한다. 이걸 분석하려면 일일이 파일 경로를 알아야 하고, 파티션도 직접 지정해줘야 하고 불편한 점이 많다. 마치 RDB의 테이블처럼 쿼리로 쉽게 다룰 수 있게 만드는게 오픈 테이블 포맷이다.
| 기능 | 설명 |
|---|---|
| 스키마 진화 | 테이블 구조 변경 (컬럼 추가/삭제/수정) 가능 |
| 타임 트래블 | 이전 시점의 데이터로 쿼리 가능 |
| ACID 트랜잭션 | 데이터 업데이트/삭제 시 충돌 없이 안전하게 처리 |
| 파티셔닝 최적화 | 쿼리 성능 향상을 위한 파티션 자동 처리 |
| 버전 관리 | 데이터 변경 이력 관리 가능 |
| 포맷 | 특징 | 대표 사용자 |
|---|---|---|
| Apache Iceberg | 메타데이터 계층 구조, Flink/Spark/FastQuery에 강함 | Netflix, Apple 등 |
| Apache Hudi | 실시간 데이터 처리에 강함 (UPSERT 중심) | Uber |
| Delta Lake | Databricks 기반, Spark와 최적화 | Databricks, Microsoft 등 |
| 항목 | 기존 파일 시스템 | 오픈 테이블 포맷 |
|---|---|---|
| 저장 방식 | 파일 단위 (경로로 접근) | 테이블 단위 (SQL처럼 접근) |
| 스키마 변경 | 수작업 필요 | 자동 반영 |
| 병합/삭제 | 어렵고 오류 가능 | 트랜잭션으로 안정적 |
| 쿼리 성능 | 파티션 수동 지정 | 최적화 자동 처리 |
스키마 진화(Schema Evolution) 는 Iceberg, Delta Lake, Hudi 같은 오픈 테이블 포맷의 핵심 기능 중 하나이다. 기존 테이블의 구조(스키마)를 변경해도 데이터를 그대로 유지하면서 쿼리나 작업을 계속할 수 있는 기능이다.
| 변화 유형 | 지원 여부 | 설명 |
|---|---|---|
| 컬럼 추가 | 예 | 기존 데이터는 null로 처리됨 |
| 컬럼 삭제 | 예 | 메타데이터에서 제거됨 (데이터는 물리적으로 남을 수 있음) |
| 컬럼 이름 변경 | 예 | 내부 ID 기반으로 관리되기 때문에 안전하게 변경 가능 |
| 컬럼 순서 변경 | 예 | 논리적으로만 변경 가능 (물리 순서와 무관) |
| 컬럼 타입 변경 | 제한적 | 호환 가능한 타입 간에만 변경 가능 (ex. int → long, float → double 등) |
-- 기존 테이블에 컬럼 추가
ALTER TABLE users ADD COLUMN email STRING;
-- 기존 컬럼 이름 변경
ALTER TABLE users RENAME COLUMN age TO user_age;
-- 기존 컬럼 삭제
ALTER TABLE users DROP COLUMN deprecated_field;
| 항목 | 스키마 진화가 미치는 영향 |
|---|---|
| 차원 테이블 확장성 | 컬럼 추가/삭제가 유연하게 가능 |
| 조인 안정성 | 컬럼 이름 변경 시 쿼리 유지 |
| 변경 이력 추적 | 스냅샷으로 스키마 변경 이력 관리 |
| 사실 테이블 구조 변경 대응 | 새 지표 추가 등 구조 확장이 쉬움 |
타임 트래블(Time Travel)은 Iceberg, Delta Lake, Apache Hudi 같은 오픈 테이블 포맷의 대표적인 기능 중 하나이다.이 기능은 데이터 분석과 데이터 품질 관리에서 유연성과 안정성을 제공한다.
과거 특정 시점의 데이터 또는 테이블 상태로 되돌아가서 조회할 수 있는 기능이다.
마치 "데이터 타임머신" 같은 개념입니다.
이전 버전의 데이터가 스냅샷(Snapshot) 형태로 저장되어 있어서,
그 시점의 데이터 상태를 그대로 다시 쿼리하거나 복원할 수 있어요.
Iceberg는 각 데이터 변경 시 마다 스냅샷(Snapshot) 을 생성한다.
| 항목 | 설명 |
|---|---|
| 정의 | 과거 특정 시점의 데이터 상태로 되돌아가 조회하는 기능 |
| 주요 목적 | 실수 복구, 이력 조회, 시점별 리포트 생성 등 |
| 사용 방식 | TIMESTAMP AS OF, VERSION AS OF, SNAPSHOT ID |
| Iceberg 방식 | 스냅샷 기반, 메타데이터로 관리, 데이터는 불변성 유지 |
-- 특정 Snapshot ID 기준으로 조회
SELECT * FROM sales_table.snapshots WHERE snapshot_id = 918273645;
-- 특정 Timestamp 기준으로 조회
SELECT * FROM sales_table TIMESTAMP AS OF '2024-12-31T23:59:59';
-- Snapshot 버전 넘버로 조회
SELECT * FROM sales_table VERSION AS OF 3;
Merge-on-read와 Merge-on-write는 Apache Iceberg, Hudi, Delta Lake 같은 오픈 테이블 포맷에서 업데이트(Update)나 삭제(Delete) 같은 변경 작업을 어떻게 처리할지에 대한 전략이다. Iceberg는 기본적으로 Merge-on-Write를 따른다. 하지만 Flink나 일부 엔진에서는 Merge-on-Read도 지원하며, 상황에 따라 전략을 선택할 수 있다.
| 항목 | Merge-on-Write | Merge-on-Read |
|---|---|---|
| 병합 시점 | 쓰기 시점에서 병합 | 읽기 시점에서 병합 |
| 쓰기 성능 | 느림 (병합 비용 발생) | 빠름 (로그만 저장) |
| 읽기 성능 | 빠름 (병합 완료된 파일만 읽음) | 느림 (파일 + 로그 병합 필요) |
| 적합한 환경 | 읽기 많은 배치 분석 환경 | 변경이 잦은 실시간 스트리밍 환경 |
| 예시 포맷 적용 | Iceberg (기본), Delta Lake | Hudi, Flink on Iceberg (옵션에 따라) |
예시 흐름:
- 원본 파일: data-file-1.parquet
- UPDATE 수행 → 새로운 병합 파일 생성: data-file-2.parquet
- 읽을 때 data-file-2만 읽으면 됨
예시 흐름:
파티셔닝 최적화(Partitioning Optimization) 는 대규모 데이터 처리에서 쿼리 성능 향상을 위한 핵심 전략 중 하나이다. 특히 Iceberg 같은 오픈 테이블 포맷은 기존 방식의 단점을 개선한 스마트한 파티셔닝 기능을 제공한다.
파티셔닝이란 데이터를 특정 컬럼 값 기준으로 나누어 저장하는 것이다.
예: event_date 기준으로 하루 단위 파티션을 만들면
| 항목 | 기존 방식 (예: Hive) | Iceberg 방식 |
|---|---|---|
| 파티션 방식 | 디렉터리 기반 | 메타데이터 기반 (숨겨진 파티션) |
| 컬럼 변경 시 대응 | 전체 재생성 필요 | 스키마 진화 가능 |
| 쿼리 최적화 | 명시적 필터 필요 | 자동 파티션 필터 적용 |
| 파티션 전략 | 정적 (col=value) | Identity, Bucket, Truncate 등 지원 |
| 성능 및 유연성 | 제한적 | 고성능, 높은 유연성 |
Iceberg는 기존의 단점을 해결하고, 더 유연하고 똑똑한 방식을 사용한다
예:
쿼리에서 단순히 WHERE event_time = '2025-04-06'이라 해도
→ Iceberg는 내부적으로 event_date 파티션만 읽음
컬럼 값을 기반으로 다양한 방식으로 파티셔닝 가능해서 사용자가 쿼리 패턴에 맞게 파티션 전략을 설계할 수 있다.
| 파티션 타입 | 예시 |
|---|---|
| Identity | country → 그대로 사용 |
| Truncate | zipcode → 앞 3자리만 저장 |
| Bucket | user_id → 해시로 N개의 버킷으로 |
| Year/Month/Day | event_time → 연/월/일 추출 |
Iceberg는 파티션 전략도 진화할 수 있음 (스키마 진화처럼)
예: 기존 day 단위 → month 단위로 변경 가능
→ 데이터 재작성 없이도 쿼리 가능
예시
-- Iceberg 테이블 생성 시 파티셔닝 설정 CREATE TABLE logs ( id BIGINT, user_id STRING, event_time TIMESTAMP, action STRING ) PARTITIONED BY (days(event_time), bucket(16, user_id));
- 날짜와 user_id 기준으로 파티셔닝
- 쿼리 시 자동으로 필터 적용되어 성능 향상
Apache Iceberg에서 말하는 메타데이터 계층화(Metadata Layering) 는
기존 Hive 스타일 테이블과는 완전히 다른 고급 관리 체계를 의미한다. Iceberg는 테이블의 구조와 상태를 계층적인 메타데이터 파일로 관리함으로써
데이터 변경 이력, 스냅샷, 파티션, 스키마 등을 효율적이고 안전하게 추적할 수 있게 해준다. Iceberg의 메타데이터 계층화는
단순한 파일 목록을 넘어서 스냅샷, 통계, 파티션, 스키마, 변경 이력 등을
정교하게 관리할 수 있도록 설계된 구조이다. 덕분에 Iceberg는 신뢰성 있는 분석, 안전한 변경, 고성능 쿼리를 모두 만족시킬 수 있다.
Iceberg는 아래와 같은 다단계 메타데이터 파일 구조로 구성되어 있다:
| 계층 | 설명 |
|---|---|
| Manifest List | 스냅샷에 포함된 manifest 파일들의 목록 (즉, 한 번의 쿼리에 필요한 데이터 목록) |
| Manifest | 여러 data file(Parquet 등)의 목록과 관련 메타 정보 (파티션, 통계 등) |
| Data File | 실제 사용자 데이터 (Parquet, ORC 등) |
Iceberg Table
├── metadata/
│ ├── v1.metadata.json ← 스키마, 파티션 전략, 최신 스냅샷 ID 등
│ └── snapshots/
│ ├── snapshot-001
│ └── snapshot-002
│ ├── manifest-list.avro
│ └── manifest-1.avro
│ └── data-file-1.parquet
│ └── data-file-2.parquet
| 항목 | 설명 |
|---|---|
| 변경 추적 | 각 변경 시점마다 스냅샷 생성. 변경 이력 추적 가능 |
| 타임 트래블 | 이전 스냅샷으로 복원하거나 조회 가능 |
| 쿼리 성능 향상 | Manifest에 파티션 및 통계 정보가 있어서 Pruning 가능 |
| 동시성 제어 (ACID) | 메타데이터 파일을 원자적으로 교체하는 방식으로 충돌 방지 |
| Garbage Collection | 오래된 snapshot과 관련된 data file을 안전하게 정리 가능 |
| 항목 | Hive 스타일 테이블 | Iceberg (메타데이터 계층화) |
|---|---|---|
| 메타데이터 저장 | Hive Metastore에 저장 | 테이블 내부에 JSON/AVRO 파일로 저장 |
| 스냅샷 지원 | 없음 | 있음 (버전 관리 가능) |
| 성능 최적화 | 파티션 디렉터리 기반 | Manifest 통한 정밀한 pruning |
| 트랜잭션 | 외부 도구 필요 (e.g. Hive ACID) | 기본 제공 (ACID 지원) |