컴팩션(Compaction)과 메타데이터 관리
Delta Lake vs Iceberg 2026: Which Table Format Wins? — 미상 (실전 프로덕션 경험 기반 블로그, 2026) Where Iceberg Falls Short (p.6), Performance — Real Numbers 중 Small file handling/Metadata overhead (pp.8-9), The Bottom Line (p.13)
이 모듈을 다 읽으면
- Iceberg의 컴팩션이 왜 엔진별 오케스트레이션을 필요로 했는지, 그리고 최근 어떻게 개선되고 있는지 설명할 수 있다
- merge-on-read와 copy-on-write 방식의 차이와 각각의 트레이드오프를 설명할 수 있다
- 메타데이터(스냅샷/매니페스트) 누적 문제와 만료(expiration) 전략의 필요성을 설명할 수 있다
작은 파일이 많이 쌓이면 쿼리 성능이 크게 저하되는 문제는 Iceberg와 Delta Lake 공통이다. 원문은 'Iceberg는 Delta의 OPTIMIZE 같은 원클릭 컴팩션이 없다'고 단정하지만, 이는 점점 낡은 서술이 되고 있다 — Spark의 rewrite_data_files 프로시저, Snowflake 관리형 Iceberg 테이블, AWS S3 Tables의 자동 백그라운드 컴팩션 등으로 격차가 빠르게 좁혀지고 있다. 또한 Iceberg v2의 merge-on-read 방식(삭제 파일 누적)이 컴팩션을 더 중요하게 만드는 구조적 이유이며, 스냅샷/매니페스트 메타데이터도 주기적으로 만료시키지 않으면 무한정 누적된다.
왜 작은 파일이 문제인가
스트리밍 수집이나 빈번한 마이크로배치 쓰기는 필연적으로 작은 파일을 많이 만든다. 파일이 작을수록 파일 오픈/클로즈 오버헤드, 메타데이터 읽기 오버헤드가 데이터 자체를 읽는 시간에 비해 상대적으로 커지고, 병렬 처리 단위(태스크)당 처리할 데이터가 적어 스케줄링 오버헤드도 커진다. 원문이 Delta Lake 사례로 든 것처럼 '5만 개의 작은 파일이 500개의 ~128MB 파일로 압축되면 쿼리가 10배 빨라질 수 있다'는 방향성은 Iceberg 테이블에도 동일하게 적용된다.
Iceberg에서 컴팩션은 rewrite_data_files라는 스토어드 프로시저로 수행한다 (Spark SQL 확장 기준: CALL catalog.system.rewrite_data_files(table => '...')). 목표 파일 크기, 부분 진행(partial progress) 여부, 정렬 순서 등을 옵션으로 지정할 수 있다.
핵심 포인트
- 작은 파일이 많으면 파일 오픈/메타데이터 오버헤드와 스케줄링 오버헤드가 커져 쿼리 성능이 크게 저하된다
- 스트리밍/마이크로배치 수집은 구조적으로 작은 파일을 많이 만들어내는 경향이 있다
- Iceberg는 rewrite_data_files 프로시저(Spark 기준)로 컴팩션을 수행하며 목표 파일 크기·정렬 순서를 옵션으로 지정할 수 있다
컴팩션 생태계 변화 — 정정
정정 — 원문은 'Iceberg에는 모든 엔진에서 그냥 동작하는 Delta의 OPTIMIZE 같은 빌트인 동등물이 없다'고 단정적으로 서술한다. 이는 부분적으로만 맞는 서술이며 빠르게 낡아가고 있다.
첫째, Spark를 쓰는 경우 rewrite_data_files 프로시저는 SQL 한 줄로 실행되는 만큼 Delta의 OPTIMIZE와 사용자 경험 차이가 크지 않다. 둘째, 더 중요한 변화는 '테이블을 누가 관리하는가'에 달려 있다는 점이다. Snowflake의 관리형 Iceberg 테이블은 백그라운드에서 자동으로 컴팩션과 정리를 수행하고, AWS S3 Tables(2024년 발표)는 S3 자체에 내장된 기능으로 Iceberg 테이블의 컴팩션·스냅샷 만료·미참조 파일 정리를 자동으로 수행한다. 즉 '엔진마다 수동 오케스트레이션이 필요하다'는 서술은 셀프 매니지드(자체 관리) Iceberg 테이블에는 여전히 유효하지만, 플랫폼이 관리하는(managed) Iceberg 테이블에는 더 이상 정확하지 않다.
둘째로 짚을 부분은 Databricks의 Tabular 인수(2024년)다. Tabular는 Iceberg의 원 창시자(Ryan Blue 등)가 만든 회사로, 이 인수로 Databricks가 Iceberg 핵심 전문성을 사내로 확보하게 되었다. 이는 Delta Lake UniForm이 Iceberg 호환 메타데이터를 함께 쓰는 방향으로 밀어붙이는 배경이기도 하다.
핵심 포인트
- Spark의 rewrite_data_files 프로시저는 Delta의 OPTIMIZE와 사용자 경험 차이가 크지 않다
- Snowflake 관리형 Iceberg 테이블, AWS S3 Tables(2024) 등 플랫폼 관리형 Iceberg는 컴팩션·스냅샷 만료를 자동으로 수행한다
- '모든 엔진에서 수동 오케스트레이션 필요'라는 서술은 셀프 매니지드 테이블에만 유효하며 관리형 서비스에는 더 이상 정확하지 않다
- Databricks의 Tabular 인수(2024, Iceberg 원 창시자들의 회사)는 두 진영의 경계를 흐리는 배경이다
Merge-on-Read vs Copy-on-Write
원문이 다루지 않는, 그러나 컴팩션 논의에 핵심적인 개념이 있다. Iceberg v2부터는 행 단위 UPDATE/DELETE/MERGE를 두 가지 방식으로 처리할 수 있다.
Copy-on-Write(COW)는 영향을 받는 데이터 파일 전체를 즉시 다시 써서 새 파일로 교체하는 방식이다. 쓰기 비용은 크지만 읽기는 항상 깨끗한 데이터 파일만 스캔하면 되므로 빠르다.
Merge-on-Read(MOR)는 원본 데이터 파일을 건드리지 않고, '이 파일의 이 행은 삭제됨'을 나타내는 가벼운 삭제 파일(positional delete 또는 equality delete, v3부터는 더 효율적인 삭제 벡터)만 추가하는 방식이다. 쓰기는 빠르지만, 읽을 때마다 데이터 파일과 삭제 파일을 병합해야 하므로 삭제 파일이 쌓일수록 읽기 성능이 저하된다.
바로 이 지점이 컴팩션이 '선택'이 아니라 '필수 운영 작업'인 이유다. MOR로 쓰기 비용을 낮춘 대가로 쌓인 삭제 파일을 주기적으로 rewrite_data_files(또는 rewrite_position_delete_files)로 병합해주지 않으면, 시간이 지날수록 읽기 성능이 서서히 나빠지는 조용한 저하가 발생한다. 원문 결론부의 '포맷이 아니라 운영 규율이 병목이다'라는 주장이 실제로 가리키는 메커니즘이 바로 이것이다.
핵심 포인트
- Copy-on-Write는 쓰기 시점에 파일을 재작성해 읽기를 빠르게 유지하고, Merge-on-Read는 쓰기를 가볍게 하는 대신 삭제 파일이 누적된다
- MOR의 삭제 파일(positional/equality delete, v3의 삭제 벡터)이 쌓이면 컴팩션 없이는 읽기 성능이 서서히 저하된다
- 컴팩션을 소홀히 하면 포맷 자체의 결함이 아니라 운영 규율 부재로 성능 문제가 발생한다 — 원문의 '포맷보다 운영 규율' 주장의 실제 메커니즘이다
메타데이터 만료 관리
커밋이 쌓일수록 스냅샷과 매니페스트 파일 수도 함께 늘어난다. expire_snapshots 프로시저로 더 이상 필요 없는 오래된 스냅샷(과 그 스냅샷만 참조하던 매니페스트·데이터 파일)을 주기적으로 만료시키지 않으면 메타데이터가 계속 누적된다.
정정 — 원문은 '시간당 커밋이 발생하는 테이블이 12개월간 2-4GB의 메타데이터를 쌓을 수 있다'는 구체적 수치를 제시하지만, 이는 커밋 빈도, 파티션 수, 스냅샷 보존 정책(retention)에 따라 크게 달라지는 예시일 뿐 Iceberg의 고정된 한계가 아니다. 스냅샷 만료 정책을 짧게 가져가면 이 수치는 훨씬 작아지고, 반대로 감사 목적으로 스냅샷을 오래 보존하면 훨씬 커질 수 있다. 즉 이 수치를 'Iceberg는 원래 메타데이터가 이 정도 쌓인다'는 고정값으로 암기하면 안 된다.
핵심 포인트
- expire_snapshots로 오래된 스냅샷과 그에 딸린 매니페스트·데이터 파일을 주기적으로 만료시켜야 메타데이터가 무한 누적되지 않는다
- 원문의 '2-4GB' 메타데이터 수치는 커밋 빈도·보존 정책에 따라 달라지는 예시일 뿐 고정된 한계가 아니다