Apache Iceberg로 구축하는 2026년 데이터 레이크하우스 실전 마이그레이션 가이드
아파치 아이스버그 테이블 포맷으로 데이터 레이크하우스를 구축하는 방법을 정리했습니다. 스키마 진화, 히든 파티셔닝, 시간 여행 쿼리와 실무 마이그레이션 절차를 다룹니다.
Apache Iceberg로 구축하는 2026년 데이터 레이크하우스 실전 마이그레이션 가이드
데이터 규모가 페타바이트 단위로 커지면서 전통적인 하이브 테이블 방식은 한계를 드러냈다. 파티션 폭발, 느린 메타데이터 스캔, 스키마 변경의 위험성이 대표적이다. 2026년 현재 아파치 아이스버그(Apache Iceberg)는 이런 문제를 해결하는 사실상의 표준 테이블 포맷으로 자리 잡았다. 스노우플레이크, 데이터브릭스, AWS, 구글 빅쿼리가 모두 아이스버그를 네이티브로 지원하면서 특정 벤더에 종속되지 않는 개방형 레이크하우스가 현실이 됐다. 이 글은 실제 마이그레이션을 앞둔 팀이 알아야 할 핵심 개념과 절차를 정리한다.
아이스버그가 하이브를 대체하는 이유
하이브 테이블은 디렉터리 목록으로 파티션을 관리한다. 쿼리 엔진이 어떤 파일을 읽을지 결정하려면 파일 시스템의 디렉터리를 일일이 나열해야 하는데, 객체 스토리지에서 이 작업은 치명적으로 느리다. 파티션이 수만 개로 늘어나면 쿼리 플래닝에만 수십 초가 걸린다. 아이스버그는 매니페스트 파일이라는 별도의 메타데이터 계층에 각 데이터 파일의 통계와 파티션 값을 기록한다. 덕분에 엔진은 디렉터리 나열 없이 메타데이터만 읽어 필요한 파일을 정밀하게 골라낸다.
두 번째 강점은 스키마 진화다. 하이브에서 컬럼 순서를 바꾸거나 이름을 변경하면 기존 데이터가 깨지는 일이 잦았다. 아이스버그는 컬럼마다 고유한 정수 ID를 부여해 이름이나 순서와 무관하게 데이터를 추적한다. 컬럼 추가, 삭제, 이름 변경, 타입 확장이 데이터 재작성 없이 메타데이터 조작만으로 즉시 완료된다. 운영 중인 테이블에 새 컬럼을 붙여야 할 때 다운타임 없이 안전하게 적용할 수 있다는 뜻이다.
세 번째는 히든 파티셔닝이다. 하이브에서는 사용자가 파티션 컬럼을 직접 명시하고 쿼리에서도 그 컬럼을 기억해 필터링해야 했다. 아이스버그는 days(ts)나 bucket(16, id) 같은 변환 규칙을 테이블 정의에 숨겨두고, 사용자가 원본 타임스탬프로만 필터링해도 자동으로 파티션 프루닝을 수행한다. 파티션 전략을 나중에 바꿔도 기존 쿼리를 수정할 필요가 없다.
테이블 생성과 시간 여행 쿼리
스파크나 트리노에서 아이스버그 테이블을 만드는 것은 간단하다. 카탈로그를 설정한 뒤 표준 SQL로 정의하면 된다.
CREATE TABLE lakehouse.sales.orders (
order_id BIGINT,
customer_id BIGINT,
amount DECIMAL(12,2),
created_at TIMESTAMP
)
USING iceberg
PARTITIONED BY (days(created_at), bucket(32, customer_id));
아이스버그의 강력한 기능 중 하나는 스냅숏 기반 시간 여행이다. 모든 커밋이 스냅숏으로 기록되므로 특정 시점의 데이터를 그대로 조회할 수 있다. 데이터 파이프라인에서 잘못된 배치가 들어갔을 때 이전 스냅숏으로 즉시 롤백하는 것도 가능하다.
SELECT * FROM lakehouse.sales.orders
FOR SYSTEM_TIME AS OF '2026-07-01 00:00:00';
CALL lakehouse.system.rollback_to_snapshot('sales.orders', 8291047382910);
이런 기능은 감사 요구가 강한 금융이나 커머스 도메인에서 특히 가치가 크다. 실수로 삭제한 데이터를 복구하거나, 리포트 수치가 어제와 다른 이유를 스냅숏 비교로 추적할 수 있다.
실무 마이그레이션 절차와 유지보수
기존 하이브 테이블을 아이스버그로 옮길 때는 두 가지 전략이 있다. 데이터를 그대로 두고 메타데이터만 생성하는 인플레이스 마이그레이션과, 새 위치로 데이터를 다시 쓰는 방식이다. 데이터가 수십 테라바이트라면 snapshot 프로시저로 원본을 건드리지 않고 아이스버그 뷰를 먼저 만들어 검증한 뒤 migrate로 전환하는 편이 안전하다. 검증 단계에서 쿼리 결과가 원본과 일치하는지 반드시 대조해야 한다.
마이그레이션 이후에는 유지보수 작업이 성능을 좌우한다. 스트리밍 인제스트로 작은 파일이 계속 쌓이면 읽기 성능이 떨어지므로 rewrite_data_files로 주기적으로 컴팩션을 수행해야 한다. 오래된 스냅숏과 고아 파일은 expire_snapshots와 remove_orphan_files로 정리해 스토리지 비용을 관리한다. 실무에서는 이런 작업을 하루 한 번 야간 배치로 자동화하는 것이 일반적이다. 컴팩션 목표 파일 크기는 128메가바이트에서 512메가바이트 사이가 무난하며, 워크로드가 스캔 위주라면 크게, 지연 시간이 중요하면 작게 잡는다.
카탈로그 선택도 중요하다. 2026년에는 아이스버그 REST 카탈로그가 표준으로 정착해 여러 엔진이 하나의 카탈로그를 공유하며 커밋 충돌을 원자적으로 처리한다. 락 관리와 커밋 조정을 카탈로그가 맡아주므로, 스파크로 쓰고 트리노로 읽고 플링크로 스트리밍하는 다중 엔진 환경도 안정적으로 운영할 수 있다. 개방형 포맷의 진짜 가치는 이렇게 도구를 자유롭게 조합할 수 있다는 데 있다.
성능 최적화와 파일 크기 전략
레이크하우스의 체감 성능은 결국 얼마나 적은 파일을 얼마나 정확하게 읽느냐에 달려 있다. 아이스버그는 매니페스트에 각 데이터 파일의 컬럼별 최소값과 최대값을 통계로 담아둔다. 쿼리 조건이 특정 범위를 지정하면 엔진은 이 통계를 보고 조건에 걸리지 않는 파일을 통째로 건너뛴다. 이를 파일 스키핑이라 부르며, 데이터를 파티션 키뿐 아니라 자주 필터링하는 컬럼 기준으로 정렬해두면 스키핑 효율이 크게 올라간다. 실무에서는 정렬 순서를 지정하는 소트 오더를 테이블에 설정해 컴팩션 시 자동으로 정렬 상태를 유지하게 한다.
작은 파일 문제는 스트리밍 인제스트를 하는 모든 레이크하우스가 겪는 고질병이다. 초당 수백 건씩 들어오는 이벤트를 곧바로 쓰면 수 킬로바이트짜리 파일이 수만 개로 쌓이고, 매니페스트가 비대해져 쿼리 플래닝 자체가 느려진다. 해결책은 두 단계다. 첫째, 인제스트 단계에서 일정 크기가 찰 때까지 버퍼링해 한 번에 큰 파일로 쓰는 것이다. 둘째, 그래도 남는 작은 파일은 야간 컴팩션으로 병합한다. 여기에 매니페스트 자체를 재작성하는 작업까지 주기적으로 돌리면 메타데이터 계층도 가볍게 유지된다.
데이터 거버넌스 관점에서도 아이스버그는 강력하다. 컬럼 수준의 접근 제어, 태그와 브랜치를 활용한 데이터 실험, 스키마 변경 이력 추적이 모두 메타데이터 계층에서 이뤄진다. 특히 브랜치 기능을 쓰면 프로덕션 테이블을 건드리지 않고 별도 브랜치에서 대규모 백필이나 스키마 변경을 검증한 뒤, 문제가 없을 때만 메인으로 병합할 수 있다. 데이터 파이프라인에도 코드처럼 안전한 실험 공간을 만들어주는 셈이다. 이런 기능들이 결합되면서 아이스버그는 단순한 파일 포맷을 넘어 신뢰할 수 있는 데이터 플랫폼의 기반으로 자리 잡았다.