Apache Iceberg Rust 0.10: 네이티브 Rust 구현이 Lakehouse 운영에 가져오는 변화
요약
Apache Iceberg Rust(iceberg-rust) 가 2026년 7~8월 0.10 / 0.10.1 을 출시하며 스냅샷 만료 액션, 스키마 변경 API, 코덱 확장을 추가했다. 이 프로젝트는 Java SDK와 Python SDK(PyIceberg) 외에 Rust 네이티브로 Iceberg 스펙 전체를 구현하는 세 번째 공식 SDK다.
아직 Java SDK보다 기능 커버리지가 낮지만, 세 가지 이유에서 Lakehouse 운영자가 주목해야 한다.
- DataFusion 직접 통합:
iceberg-datafusion크레이트는 DataFusion 쿼리 엔진에서 Iceberg 테이블을 네이티브 소스로 노출한다. dbt Core 2.0의 Fusion 엔진, Arrow Ballista, InfluxDB IOx 등 DataFusion 기반 엔진이 이 경로로 Iceberg를 읽는다. - pyiceberg-core: PyO3 바인딩으로 Python에서 Rust 성능을 쓰는 레이어다. PyIceberg 0.12부터 Java SDK 의존 없이 파일 I/O를 Rust로 가속할 수 있다.
- 임베디드 운영 도구: 컴팩션 서비스, 고아 파일 정리, 스냅샷 관리 데몬을 Rust로 작성하면 JVM 없이 저메모리 환경(컨테이너, 사이드카)에서 실행 가능하다.
배경: 왜 Java·Python 외에 Rust 구현이 필요한가
Java SDK의 강점과 한계
Java SDK는 Iceberg 스펙을 가장 완벽하게 구현하며, Spark·Flink·Hive·Trino가 이를 직접 의존한다. 성숙도와 호환성은 최고 수준이다. 그러나 JVM을 올려야 하므로 시작 비용이 크고, 사이드카·CLI 도구 등 소규모 프로세스에 탑재하기 무겁다.
PyIceberg의 역할
PyIceberg는 Python 생태계(pandas, polars, DuckDB, Airflow)와 Iceberg를 연결한다. 그러나 파일 I/O 처리에서 Java SDK보다 느리고, 대규모 manifest·data file 처리 시 병목이 생긴다.
Rust 구현의 위치
Rust는 GC 없이 C/C++ 수준의 성능을 내면서 메모리 안전성을 보장한다. 컴팩션 서비스·스냅샷 정리 데몬처럼 높은 I/O 처리량이 필요하지만 JVM을 올리기 부담스러운 도구 작성에 적합하다. DataFusion 생태계와의 자연스러운 통합도 큰 이유다.
iceberg-rust 아키텍처
핵심 크레이트 설명
- iceberg: 코어 라이브러리.
Table,Snapshot,Schema,PartitionSpec,SortOrder타입과Catalog,TableBuilder,Transaction트레이트를 정의한다. - iceberg-catalog-rest: REST 카탈로그 스펙 클라이언트. Apache Polaris, Project Nessie, Unity Catalog 등과 연결된다.
- iceberg-catalog-glue: AWS Glue Data Catalog를 Iceberg 카탈로그로 쓰는 구현체.
- iceberg-datafusion:
iceberg::Table을 DataFusionTableProvider로 노출해 SQL 쿼리를 Iceberg 스캔으로 변환한다. - pyiceberg-core: PyO3로 Python에 Rust 핵심 I/O를 노출하는 바인딩.
0.10 릴리스 핵심 변화
1. update_schema Action — 컬럼 추가·삭제
0.10 이전에는 Rust로 Iceberg 스키마를 변경할 방법이 없었다. 이번 릴리스에서 UpdateSchemaTransaction 빌더가 추가됐다.
use iceberg::TableUpdate;
let table = catalog.load_table(&table_ident).await?;
let mut tx = table.new_transaction(None);
tx.update_schema(
table.metadata().current_schema().clone(),
|builder| {
builder
.add_column(None, "new_column", Type::Primitive(PrimitiveType::String))?
.delete_column("old_column")
},
)?;
tx.commit(&catalog).await?;컬럼 추가는 Iceberg의 backward-compatible 변경이므로, 기존 스냅샷을 읽는 엔진은 영향받지 않는다. 컬럼 삭제 후에는 기존 파일에 해당 컬럼 데이터가 남아 있지만, 신규 스캔에서는 null로 처리된다.
2. ExpireSnapshotsAction — 스냅샷 만료 자동화
과거 스냅샷과 그에 연결된 데이터 파일을 정리하는 high-level API가 추가됐다.
use iceberg::action::ExpireSnapshotsAction;
let action = ExpireSnapshotsAction::builder()
.table(table.clone())
.older_than(chrono::Utc::now() - chrono::Duration::days(7))
.retain_last(5) // 최소 5개 스냅샷 유지
.build();
let result = action.execute(&catalog, &file_io).await?;
println!("Expired {} snapshots, freed {} bytes",
result.expired_snapshots, result.bytes_freed);history.expire 설정에 명시된 보존 정책을 자동으로 존중하며, 아직 활성 스냅샷이 참조하는 파일은 삭제하지 않는다.
3. purge_table — Catalog 트레이트 확장
Catalog 트레이트에 purge_table 메서드가 추가됐다. 기존 drop_table은 카탈로그 메타데이터만 삭제했는데, purge_table은 카탈로그 항목과 함께 데이터 파일까지 삭제한다.
// 카탈로그 메타데이터만 삭제 (데이터 파일 유지)
catalog.drop_table(&table_ident).await?;
// 메타데이터 + 모든 데이터 파일 삭제 (되돌릴 수 없음)
catalog.purge_table(&table_ident).await?;4. 코덱 확장 — Snappy, Zstd·Gzip 레벨 지정
Parquet 파일 쓰기 시 압축 코덱 선택 폭이 넓어졌다.
use iceberg::io::CompressionCodec;
// Snappy (빠른 압축/해제, 중간 압축률)
let codec = CompressionCodec::Snappy;
// Zstd (압축률·속도 균형, 레벨 1~22)
let codec = CompressionCodec::Zstd { level: 3 };
// Gzip (최고 압축률, 느린 속도, 레벨 1~9)
let codec = CompressionCodec::Gzip { level: 6 };이전 버전은 Zstd 기본값만 지원했다. Snappy 추가로 실시간 쓰기 경로에서 CPU 압축 비용을 줄이는 선택지가 생겼다.
5. DataFusion 53 + Arrow 58 업그레이드
iceberg-datafusion 크레이트가 DataFusion 53, Apache Arrow 58로 업그레이드됐다. DataFusion의 새 TableProvider API와 Arrow의 Utf8View 지원을 활용한다. 0.9에서 0.10으로 마이그레이션 시 DataFusion 버전도 함께 올려야 한다.
pyiceberg-core: Python에서 Rust 성능 쓰기
pyiceberg-core는 iceberg-rust 코어의 PyO3 바인딩이다. PyIceberg 0.12부터 파일 I/O 레이어를 선택적으로 pyiceberg-core로 교체할 수 있다.
pip install pyiceberg-corefrom pyiceberg.catalog.rest import RestCatalog
from pyiceberg.core_backend import RustBackend # pyiceberg-core
catalog = RestCatalog("prod", **config)
table = catalog.load_table("db.events")
# Rust 백엔드로 스캔 (대형 manifest 처리 시 ~2–4× 빠름)
df = table.scan(use_backend=RustBackend()).to_arrow()Python 코드는 그대로지만, 파일 목록 조회·manifest 파싱·data file 읽기를 Rust 코드가 처리한다. 스냅샷 수 수천 개 이상의 대형 테이블에서 manifest 처리 병목이 해소된다.
0.10.1 주의: pyiceberg-core 0.10.0은 잘못된 레포지토리 ref로 빌드되어 PyPI에서 삭제됐다. 0.10.1을 사용해야 한다.
Java SDK vs PyIceberg vs iceberg-rust 비교
| 항목 | Java SDK | PyIceberg | iceberg-rust |
|---|---|---|---|
| 기능 완성도 | ✅ 최고 | ✅ 높음 | 🔶 기본 기능 |
| 런타임 | JVM (256MB+) | Python | 네이티브 (소형) |
| 파일 I/O 속도 | 빠름 | 보통 | 매우 빠름 |
| Spark/Flink 통합 | ✅ 네이티브 | ❌ 없음 | ❌ 없음 |
| DataFusion 통합 | ❌ 없음 | ❌ 없음 | ✅ 네이티브 |
| 임베디드 도구 적합성 | 낮음 | 중간 | 높음 |
| 성숙도 | 높음 (프로덕션) | 높음 | 초기~중간 |
언제 iceberg-rust를 선택하는가
iceberg-rust는 JVM 없는 환경이나 DataFusion 기반 엔진에서 Iceberg를 다뤄야 할 때 가장 적합하다. 반면 Spark·Flink 파이프라인이나 복잡한 스키마 변환이 필요한 프로덕션 파이프라인은 Java SDK가 여전히 정답이다.
✅ iceberg-rust 사용 적합 상황:
- DataFusion 기반 쿼리 엔진에서 Iceberg 읽기
- JVM 없이 경량 컴팩션·스냅샷 정리 사이드카 작성
- Python 워크플로우에서 대형 Iceberg 테이블 읽기 가속 (pyiceberg-core)
- 고성능 Lakehouse CLI 도구 개발
⚠️ Java SDK가 여전히 필요한 상황:
- Apache Spark / Flink Iceberg 통합 (공식 지원 없음)
- V2 delete 파일(positional/equality delete) 쓰기 (Rust 미구현)
- 복잡한 파티션 진화(partition evolution) 작업
- 엄격한 프로덕션 SLA: Rust SDK는 아직 0.x 버전운영 체크리스트
✅ 0.10.0 → 0.10.1로 업그레이드 확인
(pyiceberg-core 0.10.0은 PyPI에서 삭제됨)
✅ DataFusion 버전 호환성 확인
iceberg-datafusion 0.10은 DataFusion 53 의존
프로젝트의 datafusion 버전과 일치하는지 Cargo.lock 확인
✅ V2 delete 파일 사용 여부 확인
positional/equality delete는 Rust SDK가 아직 쓰기 미지원
Java SDK로 작성된 delete 파일이 있는 테이블이면 읽기는 가능하나 조심
✅ ExpireSnapshotsAction retain_last 설정 검토
최소 유지 스냅샷 수 = 가장 긴 실행 중인 쿼리 예상 시간 / 스냅샷 간격
✅ pyiceberg-core 사용 시 버전 잠금
pip install "pyiceberg-core==0.10.1" 로 고정
✅ 코덱 선택 기준 정립
실시간 쓰기 경로: Snappy (속도 우선)
아카이브 파티션: Zstd level 7~9 (압축률 우선)
호환성 최우선: Gzip (폭넓은 도구 지원)