[Iceberg] 아파치 아이스버그 주요 개념 정리
1. Apache Iceberg란?
Apache Iceberg는 대규모 분석 데이터를 위한 오픈 테이블 포맷이다. Parquet, Avro, ORC 같은 파일 포맷이 개별 파일의 데이터 저장 방식을 정의한다면, 테이블 포맷은 여러 데이터 파일을 하나의 논리적 테이블로 관리하는 규칙을 정의한다.
일반적인 데이터 레이크에서는 디렉터리와 파일 경로를 기준으로 데이터를 관리한다. 이 방식은 파일이 많아지거나 여러 작업이 동시에 데이터를 변경할 때 다음과 같은 문제를 만든다.
- 어떤 파일이 현재 테이블에 포함되는지 판단하기 어렵다.
- 쓰기 작업 도중 실패하면 불완전한 파일이 남을 수 있다.
- 스키마나 파티션 구조를 변경하기 어렵다.
- 과거 시점의 테이블 상태를 재현하기 어렵다.
Iceberg는 파일 목록과 테이블 상태를 메타데이터로 관리해 이러한 문제를 해결한다. Spark, Flink, Trino 같은 처리 엔진은 디렉터리를 직접 탐색하는 대신 Iceberg 메타데이터를 따라 필요한 파일만 찾는다.
2. 주요 특징
2.1 ACID 트랜잭션
Iceberg의 변경 작업은 새로운 메타데이터를 만든 뒤, 카탈로그가 가리키는 현재 메타데이터 위치를 원자적으로 교체하는 방식으로 커밋된다. 커밋이 완료되기 전의 중간 상태는 독자에게 노출되지 않는다.
여러 쓰기 작업이 동시에 실행될 때는 낙관적 동시성 제어를 사용한다. 커밋 대상이 이미 변경되었다면 충돌을 감지하고 작업을 재시도하거나 실패시켜 테이블 상태를 보호한다.
2.2 스냅샷과 타임 트래블
테이블 변경이 커밋될 때마다 새로운 스냅샷(snapshot) 이 생성된다. 스냅샷은 특정 시점에 유효한 데이터 파일의 집합을 나타낸다.
이를 이용하면 다음과 같은 작업이 가능하다.
- 특정 시점이나 스냅샷 ID를 기준으로 과거 데이터 조회
- 잘못된 변경 이전 상태 확인과 롤백
- 동일한 스냅샷을 사용한 재현 가능한 분석
스냅샷은 데이터 파일 전체를 매번 복사하지 않는다. 변경되지 않은 매니페스트와 데이터 파일을 재사용하므로 메타데이터 중심으로 버전을 관리할 수 있다.
2.3 안전한 스키마 진화
Iceberg는 컬럼 이름이나 위치가 아니라 고유한 필드 ID로 컬럼을 추적한다. 따라서 기존 데이터 파일을 즉시 다시 쓰지 않고도 컬럼 추가, 삭제, 이름 변경, 순서 변경과 일부 타입 확장을 처리할 수 있다.
2.4 히든 파티셔닝과 파티션 진화
Iceberg는 day(event_time), bucket(16, id)처럼 원본 컬럼과 변환 규칙의 관계를 파티션 스펙으로 관리한다. 사용자는 별도의 파티션 컬럼을 직접 생성하거나 쿼리 조건에 파티션 값을 명시할 필요가 없다.
파티션 전략이 바뀌어도 기존 파일을 즉시 재작성하지 않는다. 기존 데이터는 이전 파티션 스펙을 유지하고 새 데이터부터 새 스펙을 적용할 수 있다. 쿼리 엔진은 각 스펙에 맞는 필터를 계산해 두 구조를 함께 조회한다.
2.5 엔진과 스토리지의 분리
Iceberg는 특정 처리 엔진에 종속되지 않는다. 여러 엔진이 같은 테이블 메타데이터와 데이터 파일을 공유할 수 있고, 데이터는 S3 같은 오브젝트 스토리지나 HDFS 등에 저장할 수 있다.
3. Iceberg 테이블의 계층 구조

Iceberg 테이블은 다음 순서로 실제 데이터 파일에 도달한다.
Catalog
└─ Table Metadata (metadata.json)
└─ Snapshot
└─ Manifest List
└─ Manifest Files
├─ Data Files
└─ Delete Files
각 계층은 바로 아래 계층의 위치와 통계를 저장한다. 쿼리 엔진은 이 메타데이터를 단계적으로 필터링해 읽을 필요가 없는 파일을 제외한다.
3.1 카탈로그
카탈로그는 analytics.orders 같은 테이블 식별자를 현재 metadata.json 파일의 위치로 연결한다. 테이블의 최신 상태를 찾는 시작점이자, 새 메타데이터를 현재 버전으로 교체하는 커밋 지점이다.
대표적인 구현은 다음과 같다.
- REST Catalog
- Hive Metastore
- Hadoop Catalog
- JDBC Catalog
- AWS Glue Catalog
- Project Nessie
3.2 테이블 메타데이터 파일
metadata.json은 테이블 전체의 현재 구성을 정의한다.
- 현재 스키마와 필드 ID
- 파티션 스펙과 정렬 순서
- 테이블 속성과 저장 위치
- 유효한 스냅샷 목록과 현재 스냅샷
- 스냅샷 로그와 메타데이터 변경 이력
테이블 구성이 변경되면 기존 파일을 덮어쓰지 않고 새로운 메타데이터 파일을 만든다. 카탈로그가 새 파일을 가리키는 데 성공해야 변경이 최종 커밋된다.
3.3 스냅샷과 매니페스트 리스트
스냅샷은 특정 시점의 테이블 상태이며 하나의 매니페스트 리스트(manifest list) 를 가리킨다. 매니페스트 리스트에는 해당 스냅샷을 구성하는 매니페스트 파일과 다음과 같은 요약 정보가 담긴다.
- 매니페스트가 사용하는 파티션 스펙
- 파티션 값의 범위
- 추가되거나 삭제된 파일 수
쿼리 엔진은 이 통계를 사용해 조건과 관련 없는 매니페스트를 먼저 제외한다.
3.4 매니페스트 파일
매니페스트 파일은 스냅샷을 구성하는 데이터 파일 또는 삭제 파일의 목록을 저장한다. 각 항목에는 파일 경로뿐 아니라 다음 정보도 포함된다.
- 파일 상태(추가, 기존, 삭제)
- 파티션 값
- 레코드 수와 파일 크기
- 컬럼별 null 개수와 값의 상·하한 등 통계
이 통계를 이용하면 쿼리 조건을 만족할 가능성이 없는 데이터 파일을 실제로 열기 전에 제외할 수 있다.
3.5 데이터 파일과 삭제 파일
데이터 파일에는 실제 행 데이터가 저장된다. 일반적으로 Parquet, Avro, ORC 형식을 사용한다.
Iceberg v2 테이블은 기존 데이터 파일을 즉시 다시 쓰지 않고 행을 삭제할 수 있도록 삭제 파일도 사용할 수 있다. 삭제 파일은 특정 파일의 행 위치를 기록하는 position delete와 키 값을 기록하는 equality delete 방식으로 나뉜다.
파티션은 별도의 물리 계층이 아니다. 데이터 파일을 작성할 때 같은 파티션 값을 가진 행을 함께 배치하고, 그 파티션 정보는 매니페스트에 기록된다.
4. 쿼리가 데이터 파일을 찾는 과정
예를 들어 날짜 조건이 포함된 쿼리를 실행하면 다음 순서로 읽기 대상을 줄인다.
- 카탈로그에서 현재 테이블 메타데이터 위치를 조회한다.
- 현재 스냅샷과 매니페스트 리스트를 확인한다.
- 파티션 값 범위를 이용해 불필요한 매니페스트를 제외한다.
- 매니페스트의 파티션 정보와 컬럼 통계로 데이터 파일을 다시 필터링한다.
- 남은 데이터 파일만 처리 엔진이 읽는다.
즉 Iceberg의 성능은 단순히 데이터를 컬럼형 파일로 저장하는 데서 끝나지 않는다. 메타데이터를 인덱스처럼 사용해 파일 탐색 비용과 실제 읽기량을 함께 줄이는 것이 핵심이다.
5. 정리
- Iceberg는 파일 포맷이 아니라 여러 데이터 파일을 논리적 테이블로 관리하는 테이블 포맷이다.
- 카탈로그에서 시작해 테이블 메타데이터, 스냅샷, 매니페스트 리스트, 매니페스트 파일을 거쳐 실제 데이터 파일을 찾는다.
- 스냅샷 기반 커밋으로 ACID 트랜잭션과 타임 트래블을 제공한다.
- 필드 ID와 파티션 스펙을 메타데이터로 관리해 스키마와 파티션 구조를 안전하게 변경할 수 있다.
- 매니페스트의 파티션 정보와 컬럼 통계를 이용해 불필요한 파일을 읽기 전에 제외한다.
운영 단계에서는 스냅샷과 작은 파일이 계속 누적되므로 별도의 유지 관리가 필요하다. 관련 내용은 Apache Iceberg 테이블 유지 관리 작업과 자동화 설계에서 이어서 다룬다.
Leave a comment