핵심 요약
Lakehouse는 Data Lake의 비용·유연성 + Data Warehouse의 ACID·스키마. Iceberg는 그 표준 형식. Snowflake·Databricks·BigQuery 모두 Iceberg를 1급 시민으로 지원하면서 데이터 이동 자유도가 폭증.
- Iceberg 1.5+ (2026)
- S3 + Parquet 위에서 ACID 트랜잭션
- Schema Evolution + Partition Evolution
- Time Travel (이전 버전 쿼리)
- multi-engine: Spark·Flink·Trino·Snowflake·BigQuery·Athena 모두 지원
1. Lakehouse 아키텍처
┌─────────────────────────────────┐
│ Query Engines │
│ Spark · Trino · Flink · Athena │
└──────────────┬──────────────────┘
│
┌──────────────▼──────────────────┐
│ Iceberg (Table Format) │
│ - Snapshots, Manifests │
│ - Schema/Partition Evolution │
└──────────────┬──────────────────┘
│
┌──────────────▼──────────────────┐
│ Object Storage (S3·GCS·ADLS) │
│ Parquet files │
└─────────────────────────────────┘2. 테이블 생성·쓰기 (Spark)
# Spark + Iceberg 의존성 설정
spark = SparkSession.builder \
.config("spark.sql.extensions", "org.apache.iceberg.spark.extensions.IcebergSparkSessionExtensions") \
.config("spark.sql.catalog.glue", "org.apache.iceberg.spark.SparkCatalog") \
.config("spark.sql.catalog.glue.catalog-impl", "org.apache.iceberg.aws.glue.GlueCatalog") \
.config("spark.sql.catalog.glue.warehouse", "s3://my-warehouse/") \
.getOrCreate()
# 테이블 생성
spark.sql("""
CREATE TABLE glue.events.user_events (
event_id STRING,
user_id BIGINT,
event_type STRING,
timestamp TIMESTAMP,
payload MAP<STRING, STRING>
)
USING ICEBERG
PARTITIONED BY (days(timestamp), event_type)
""")
# 데이터 쓰기
df.writeTo("glue.events.user_events").append()3. Schema Evolution
# 컬럼 추가 (즉시, 데이터 rewrite 없음)
spark.sql("ALTER TABLE glue.events.user_events ADD COLUMN session_id STRING")
# 컬럼 이름 변경 (스냅샷 메타데이터만 변경)
spark.sql("ALTER TABLE glue.events.user_events RENAME COLUMN payload TO data")
# 컬럼 타입 변경 (안전한 widening: int → long)
spark.sql("ALTER TABLE glue.events.user_events ALTER COLUMN user_id TYPE BIGINT")전통 데이터레이크는 컬럼 변경이 곧 전체 rewrite. Iceberg는 메타데이터만 변경.
4. Partition Evolution
# 기존 daily 파티션 → hourly로 변경 (rewrite 없음)
spark.sql("""
ALTER TABLE glue.events.user_events
REPLACE PARTITION FIELD days(timestamp) WITH hours(timestamp)
""")
# 새 데이터부터 hourly, 기존은 daily 그대로 — 둘 다 쿼리 가능Hive·Parquet는 파티션 변경하려면 전체 rewrite. Iceberg는 새 데이터부터 적용.
5. Time Travel
# 1시간 전 상태 쿼리
SELECT * FROM glue.events.user_events
TIMESTAMP AS OF '2026-04-23 13:00:00'
# 특정 snapshot ID로
SELECT * FROM glue.events.user_events
VERSION AS OF 1234567890
# 변경 이력 조회
SELECT * FROM glue.events.user_events.snapshots
ORDER BY committed_at DESC6. ACID 트랜잭션
# MERGE INTO (UPSERT)
spark.sql("""
MERGE INTO glue.events.user_events t
USING incoming s ON t.event_id = s.event_id
WHEN MATCHED THEN UPDATE SET t.* = s.*
WHEN NOT MATCHED THEN INSERT *
""")
# DELETE
spark.sql("DELETE FROM glue.events.user_events WHERE event_type = 'test'")
# 동시 쓰기 — optimistic concurrency
# 충돌 시 자동 retry 또는 사용자 처리7. Multi-Engine 활용
# 같은 테이블을 여러 엔진에서:
# 1) Spark — ETL 작업
spark.read.table("glue.events.user_events")
# 2) Trino — 즉시 쿼리
# SELECT count(*) FROM iceberg.events.user_events
# 3) Snowflake — 대시보드
# CREATE EXTERNAL TABLE ICEBERG_TABLE_EVENTS
# USING TEMPLATE (
# SELECT ARRAY_AGG(OBJECT_CONSTRUCT(*))
# FROM TABLE(GET_ICEBERG_TABLE_FILES(...))
# )
# 4) BigQuery — analytics
# CREATE TABLE my_dataset.events
# OPTIONS(format='ICEBERG', uris=['s3://...'])데이터 한 곳, 분석 도구 자유.
8. 운영 — 유지보수
# Compaction (작은 파일 합치기)
spark.sql("CALL glue.system.rewrite_data_files(table => 'events.user_events')")
# Snapshot expiration (오래된 스냅샷 삭제)
spark.sql("CALL glue.system.expire_snapshots(table => 'events.user_events', older_than => TIMESTAMP '2026-03-23')")
# Orphan files 청소
spark.sql("CALL glue.system.remove_orphan_files(table => 'events.user_events')")9. Catalog 옵션
| Catalog | 특징 |
|---|---|
| AWS Glue | AWS 환경에서 표준 |
| Hive Metastore | 레거시 호환 |
| Nessie | Git-like branching |
| Polaris (Snowflake) | open source, Snowflake 친화 |
| Unity Catalog (Databricks) | Databricks 환경 |
| REST Catalog | 표준 인터페이스, 자체 호스팅 |
10. Iceberg vs Delta Lake vs Hudi
| 항목 | Iceberg | Delta Lake | Hudi |
|---|---|---|---|
| vendor | 중립 (Apache) | Databricks 주도 | Apache |
| Schema Evolution | ★★★★★ | ★★★★ | ★★★ |
| Time Travel | ★★★★★ | ★★★★★ | ★★★★ |
| Multi-engine | ★★★★★ | ★★★ (Databricks 우선) | ★★★ |
| 커뮤니티 | 거대·다양 | 거대·Databricks 종속 | 중간 |
2026년 시점 Iceberg가 사실상 표준. AWS·GCP·Snowflake·Databricks·Cloudflare R2 모두 지원.
11. 실측 — 운영 비용
| 워크로드 | 전통 DW | Iceberg + Athena |
|---|---|---|
| 저장 (1PB) | $25,000/월 | $23/월 (S3) |
| 쿼리 (10TB scan) | $100 | $50 (Athena) |
| 유연성 | vendor lock-in | open |

댓글 0