Apache Iceberg
고친 사람 github-actions[bot]
Apache Iceberg 는 데이터 레이크에 쌓인 파일 더미를 테이블 하나처럼 읽고 쓰게 해 주는 도구입니다. 테이블을 이루는 파일이 지금 무엇인지 따로 적어 둡니다. 그래서 여러 분석 엔진이 같은 테이블을 동시에 다룹니다. 그래도 반쯤 쓰인 결과는 보이지 않습니다.
쉽고 빠른 이해
Iceberg 는 파일 저장소에 흩어진 데이터 파일 묶음을 테이블로 다루게 합니다. 주문 기록 파일 수만 개를 orders 라는 테이블 하나로 보고 조회하는 식입니다.
이게 없으면 테이블은 폴더 하나일 뿐입니다. 누가 파일을 쓰는 도중에 읽으면 절반만 들어간 결과를 봅니다. 두 작업이 같은 폴더에 동시에 쓰면 한쪽 결과가 덮이기도 합니다.
- 데이터는 새 파일로만 씁니다. 있던 파일은 고치지 않습니다
- 이번에 테이블을 이루는 파일 목록을 새로 적습니다
- 「지금 테이블은 이 목록이다」라는 표시를 한 번에 바꿉니다
읽는 쪽은 바뀌기 전 목록이나 바뀐 뒤 목록 중 하나만 봅니다. 옛 목록도 남아 있어서 지난 시점의 테이블을 다시 읽을 수 있습니다.
대가는 파일이 계속 쌓인다는 점입니다. 옛 목록과 작은 파일을 치우는 작업을 따로 돌려야 합니다. 한 행을 자주 고치는 서비스용 데이터베이스를 대신하지도 못합니다.
상세
Apache Iceberg 는 Apache Software Foundation 이 관리하는 오픈 소스 프로젝트입니다. Netflix 에서 만들어 이 재단으로 넘어왔습니다. 파일 묶음을 테이블로 다루는 규칙을 정합니다. 그 규칙대로 읽고 쓰는 라이브러리도 함께 내놓습니다.
이 절은 테이블이 폴더 하나이던 방식의 문제에서 출발합니다. Iceberg 가 적어 두는 메타데이터의 모양을 봅니다. 그 모양 덕분에 쓰기와 읽기가 어떻게 안전해지는지도 봅니다. 이어서 지난 시점 읽기, 파티션, 열 바꾸기, 행 고치기를 봅니다. 끝으로 이 방식이 치르는 값과 Iceberg 를 고르는 경우를 봅니다.
폴더 하나이던 테이블
데이터 레이크는 여러 곳에서 생긴 데이터를 파일로 한곳에 쌓아 두는 곳입니다. 서비스 로그나 주문 기록 같은 데이터가 가공 전 모습 그대로 모입니다.
이 파일은 대개 객체 스토리지에 둡니다. 객체 스토리지는 파일을 이름 붙은 덩어리로 맡아 두는 저장소입니다. Amazon S3(Simple Storage Service)가 그런 저장소입니다. 값이 싸서 데이터를 많이 쌓아 두기 좋습니다. 이 문서에서 저장소라고 하면 이 객체 스토리지를 가리킵니다.
분석용 파일은 흔히 Parquet 으로 적습니다. Parquet 은 값을 열마다 모아 적는 파일 포맷입니다. 합계를 내는 질의처럼 열 몇 개만 읽는 일이 빨라집니다.
이런 파일을 SQL(Structured Query Language)로 조회하려면 파일 묶음을 테이블로 보는 약속이 필요합니다. 오래 쓰인 약속은 Hive 에서 왔습니다. 폴더 하나를 테이블 하나로 봅니다. 그 폴더 안의 파일은 전부 테이블의 행으로 칩니다.
폴더가 곧 테이블이면 곤란한 일이 셋 생깁니다.
| 곤란한 일 | 왜 생기나 |
|---|---|
| 쓰는 도중에 읽으면 절반만 보인다 | 파일이 하나씩 폴더에 들어간다 |
| 동시에 쓰면 한쪽이 덮인다 | 폴더에는 누가 먼저 썼는지 가리는 장치가 없다 |
| 조회마다 준비에 시간이 든다 | 어떤 파일이 있는지 폴더 목록부터 훑는다 |
셋 다 뿌리가 같습니다. 테이블을 이루는 파일이 무엇인지 적어 둔 곳이 폴더 말고는 없습니다.
객체 스토리지에서는 이 문제가 더 커집니다. 파일 시스템처럼 폴더 이름을 한 번에 바꾸는 기능이 없습니다. 다 쓴 결과를 임시 폴더에 두었다가 이름을 바꿔 한 번에 드러내는 방법을 쓸 수 없습니다.
테이블 포맷
Iceberg 는 폴더 대신 목록을 믿습니다. 어떤 파일이 테이블에 들어 있는지를 폴더와 따로 적어 둡니다. 목록에 없는 파일은 폴더 안에 있어도 테이블의 일부가 아닙니다.
이렇게 따로 적어 둔 기록이 메타데이터입니다. 메타데이터는 데이터를 설명하는 데이터라는 뜻입니다. Iceberg 에서는 테이블의 열 구성과 파일 목록이 메타데이터입니다.
테이블 포맷은 파일 묶음을 테이블로 다루는 이런 규칙입니다. Delta Lake 와 Apache Hudi 도 같은 일을 하는 테이블 포맷입니다. Parquet 같은 파일 포맷은 파일 하나 안의 바이트를 정합니다. 테이블 포맷은 그 파일 여럿을 한 테이블로 묶는 규칙을 정합니다.
쿼리 엔진(분석 엔진)은 SQL 을 받아 파일을 읽고 결과를 돌려주는 프로그램입니다. Spark 나 Trino 가 그런 엔진입니다. 아래에서는 줄여서 엔진이라고 씁니다.
Iceberg 에는 따로 띄우는 서버가 없습니다. 엔진들이 Iceberg 라이브러리를 품고 규칙대로 파일을 읽고 씁니다.
메타데이터의 겹
Iceberg 는 파일 목록을 한 장에 몰아 적지 않습니다. 여러 겹으로 나눠 적습니다. 테이블이 아무리 커도 바뀐 부분만 새로 적으려는 것입니다. 맨 아래 데이터 파일부터 한 겹씩 올라가며 봅니다.
맨 아래 데이터 파일은 행이 담긴 Parquet 파일입니다. 한번 쓰면 다시 고치지 않습니다.
매니페스트는 데이터 파일의 목록입니다. 파일마다 경로와 행 수를 적습니다. 열마다 가장 작은 값과 가장 큰 값도 함께 적어 둡니다. 이 값 덕분에 엔진은 파일을 열지 않고도 건너뛸 파일을 고릅니다. 주문 시각의 최댓값이 어제인 파일은 오늘 주문을 찾는 질의에서 열 필요가 없습니다.
매니페스트 리스트는 매니페스트들의 목록입니다. 한 시점의 테이블을 이루는 매니페스트를 모읍니다.
스냅샷은 이렇게 모은 한 시점의 테이블 모습입니다. 어제 적재를 마친 뒤의 테이블과 오늘 적재를 마친 뒤의 테이블은 서로 다른 스냅샷입니다. 매니페스트 리스트 하나가 스냅샷 하나입니다.
메타데이터 파일은 테이블의 맨 위 기록입니다. 열 이름과 타입, 파티션 규칙, 지금까지의 스냅샷 목록을 담습니다. 그중 어느 스냅샷이 지금 테이블인지도 적습니다. 이 파일은 JSON(JavaScript Object Notation)으로 적습니다.
파티션 규칙은 데이터를 어떤 값으로 나눠 둘지 정한 규칙입니다. 주문을 날짜별로 나눠 두는 것이 한 예입니다. 자세한 것은 뒤의 「숨은 파티셔닝」 절에서 봅니다.
카탈로그는 테이블 이름과 지금 메타데이터 파일의 위치를 짝지어 둡니다. orders 테이블을 읽으려는 엔진은 카탈로그부터 묻습니다.
아래 그림은 지금 본 겹들을 카탈로그에서 데이터 파일까지 위에서 아래로 그린 것입니다. 화살표는 위 것이 아래 것을 가리킨다는 뜻입니다.
flowchart TD
C["카탈로그"] --> M["메타데이터 파일"]
M --> L["매니페스트 리스트"]
L --> F1["매니페스트"]
L --> F2["매니페스트"]
F1 --> D1["데이터 파일"]
F1 --> D2["데이터 파일"]
F2 --> D3["데이터 파일"]
카탈로그가 가리키는 메타데이터 파일에서 출발해 화살표를 따라 내려가면 지금 테이블의 데이터 파일이 전부 나옵니다.
쓰기와 커밋
Iceberg 는 있던 파일을 고쳐 쓰지 않습니다. 새 행은 새 데이터 파일에 적습니다. 그 파일을 가리키는 매니페스트와 매니페스트 리스트, 메타데이터 파일도 새로 씁니다.
새 매니페스트 리스트는 안 바뀐 옛 매니페스트를 그대로 가리킵니다. 매니페스트 가운데 새로 쓰는 것은 이번에 더한 데이터 파일을 적은 것뿐입니다. 테이블이 아무리 커도 데이터 파일 목록은 바뀐 부분만 새로 적는 셈입니다.
쓰기는 엔진이 카탈로그에서 지금 메타데이터 파일의 위치를 읽는 데서 시작합니다. 엔진은 이 옛 위치를 기억해 두었다가 마지막에 위치를 바꿔 달라고 할 때 함께 내놓습니다. 아래는 엔진이 새 행을 붙여 넣을 때 오가는 순서입니다.
sequenceDiagram
participant 엔진
participant 저장소
participant 카탈로그
엔진->>카탈로그: 지금 메타데이터 위치를 읽는다
카탈로그-->>엔진: 옛 메타데이터 파일 위치
엔진->>저장소: 새 데이터 파일을 쓴다
엔진->>저장소: 새 매니페스트와 매니페스트 리스트를 쓴다
엔진->>저장소: 새 메타데이터 파일을 쓴다
엔진->>카탈로그: 위치를 새 메타데이터 파일로 바꿔 달라
Note over 카탈로그: 위치가 처음에 읽은 옛 파일일 때만 바꾼다
카탈로그-->>엔진: 바꿨다
마지막 한 번의 교체가 커밋입니다. 앞에서 쓴 파일들은 카탈로그가 가리키기 전까지 아무도 보지 않습니다. 쓰는 도중에 엔진이 죽으면 아무도 가리키지 않는 파일만 저장소에 남습니다. 테이블은 커밋 전 모습 그대로입니다.
읽는 쪽은 시작할 때 카탈로그에서 메타데이터 파일 하나를 받습니다. 그리고 그 파일이 가리키는 스냅샷만 따라갑니다. 읽는 도중에 커밋이 일어나도 이미 잡은 스냅샷은 바뀌지 않습니다. 그래서 반쯤 쓰인 테이블을 보는 일이 없습니다.
두 작업이 동시에 커밋하면 한쪽만 이깁니다. 카탈로그는 위치가 요청한 쪽이 처음에 읽은 옛 파일일 때만 바꿔 주기 때문입니다. 진 쪽은 새 메타데이터를 읽고 제 변경을 그 위에 얹어 다시 시도합니다. 낙관적 동시성 제어는 이렇게 미리 잠그지 않고 부딪혔을 때 다시 하는 방식입니다.
다시 시도가 늘 통하는 것은 아닙니다. 두 작업이 같은 데이터 파일을 지우거나 고쳤다면 진 쪽은 실패로 끝납니다. 새 행을 붙여 넣기만 하는 작업끼리는 서로 건드리는 파일이 없어 대개 다시 시도로 풀립니다.
지난 시점 읽기
커밋해도 옛 스냅샷은 메타데이터 파일의 스냅샷 목록에 남습니다. 옛 스냅샷이 가리키는 데이터 파일도 지워지지 않습니다. 그래서 지난 시점의 테이블을 다시 읽을 수 있습니다. 이 기능을 시간 여행이라고 부릅니다.
아래는 Spark SQL 로 쓴 예입니다. 9월 1일 뒤로 주문 200건이 더 들어온 테이블을 가정했습니다. 주석은 각 질의가 돌려주는 행 수입니다.
SELECT count(*) FROM orders; -- 1200
SELECT count(*) FROM orders
TIMESTAMP AS OF '2026-09-01'; -- 1000
둘째 질의는 9월 1일 0시 시점의 스냅샷을 찾아 그 스냅샷의 파일만 읽습니다. 잘못 적재한 데이터를 찾거나 지난 보고서를 같은 데이터로 다시 뽑을 때 씁니다.
테이블을 옛 모습으로 되돌리기도 쉽습니다. 지금 스냅샷을 옛 스냅샷으로 바꾸는 커밋 하나면 됩니다. 데이터 파일은 하나도 다시 쓰지 않습니다.
숨은 파티셔닝
파티셔닝은 테이블을 어떤 값에 따라 나눠 두는 일입니다. 주문을 날짜별로 나눠 두면 하루치 조회가 그날 파일만 읽습니다.
Hive 방식에서는 날짜별로 폴더를 나누려고 order_date 같은 열을 따로 만들었습니다. 쓰는 쪽은 주문 시각에서 날짜를 뽑아 이 열을 채워야 했습니다.
읽는 쪽도 order_date 로 조건을 걸어야 필요 없는 폴더를 건너뛰었습니다. 주문 시각으로만 조건을 걸면 나눠 둔 보람 없이 전부 읽습니다.
Iceberg 는 파티션 규칙을 메타데이터 파일에 적어 둡니다. 「주문 시각에서 날짜를 뽑아 나눈다」처럼 열과 변환을 함께 적습니다. 쓰는 쪽도 읽는 쪽도 주문 시각만 다룹니다. 날짜를 뽑는 일과 파일을 건너뛰는 일은 Iceberg 가 맡습니다. 이것을 숨은 파티셔닝이라고 부릅니다.
아래는 이런 규칙을 가진 테이블을 Spark SQL 로 만드는 문장입니다.
CREATE TABLE orders (
id BIGINT,
ordered_at TIMESTAMP
) USING iceberg
PARTITIONED BY (days(ordered_at));
USING iceberg 는 이 테이블을 Iceberg 규칙으로 다루라고 Spark 에 알립니다. days(ordered_at) 가 변환입니다. 주문 시각에서 날짜를 뽑아 그 날짜별로 파일을 나눕니다.
조회할 때는 주문 시각에 조건을 겁니다. 주석은 이 질의가 여는 파일입니다.
SELECT * FROM orders
WHERE ordered_at
>= '2026-09-24'; -- 24일부터 파일만
파티션 규칙은 나중에 바꿀 수도 있습니다. 데이터가 늘어 날짜별에서 시간별로 바꾸면 새 규칙은 앞으로 쓰는 파일에만 걸립니다. 옛 파일은 옛 규칙대로 남습니다. 조회는 두 규칙의 파일을 함께 읽습니다.
열 바꾸기
스키마는 테이블이 가진 열의 이름과 타입입니다. 운영하다 보면 열을 더하고 빼고 이름을 바꿉니다. 이렇게 스키마를 고쳐 가는 일을 스키마 진화라고 부릅니다.
Iceberg 는 열마다 번호를 매겨 메타데이터 파일에 적습니다. 데이터 파일 안에도 열을 이 번호로 적습니다. 열 이름을 바꿔도 번호는 같습니다. 그래서 옛 파일을 다시 쓰지 않습니다.
이름으로 열을 찾는 방식에서는 사고가 납니다. 열 하나를 지우고 같은 이름으로 새로 더하면 옛 파일의 값이 새 열의 값으로 읽힙니다. Iceberg 에서는 새로 더한 열이 새 번호를 받습니다. 옛 값이 새 열에 섞이지 않습니다.
행 고치기와 지우기
데이터 파일은 한번 쓰면 고치지 않습니다. 이 때문에 행 하나를 지우거나 고치는 방법이 둘로 갈립니다.
행 고치기는 지우기와 쓰기를 합친 것입니다. 옛 행을 지우고 고친 행을 새 데이터 파일에 씁니다. 아래 두 방식은 옛 행을 어떻게 지우느냐에서 갈립니다.
| 방식 | 하는 일 | 비용이 덜 드는 쪽 |
|---|---|---|
| 쓰기 시 복사 (copy-on-write) | 그 행이 든 데이터 파일을 새로 다시 쓴다 | 읽기 |
| 읽기 시 병합 (merge-on-read) | 지운 행을 적은 작은 삭제 파일을 따로 쓴다 | 쓰기 |
쓰기 시 복사는 행 하나 때문에 큰 파일 하나를 다시 씁니다. 대신 읽는 쪽은 데이터 파일만 읽으면 됩니다. 읽기 시 병합은 쓰기가 가볍습니다. 대신 읽는 쪽이 데이터 파일과 삭제 파일을 맞춰 보며 지운 행을 걸러야 합니다.
삭제 파일이 쌓일수록 읽기가 느려집니다. 읽기 시 병합을 쓰는 테이블은 삭제 파일을 데이터 파일에 합쳐 넣는 작업을 가끔 돌립니다.
쌓이는 파일과 정리
Iceberg 는 지우지 않고 새로 쓰므로 파일이 계속 늘어납니다. 옛 스냅샷이 가리키는 데이터 파일이 남습니다. 커밋마다 새로 생긴 메타데이터 파일도 남습니다. 저장 비용이 늘어납니다. 메타데이터가 길어져 엔진이 읽을 파일을 고르는 데도 시간이 더 듭니다.
자주 조금씩 쓰면 작은 파일이 많이 생깁니다. 스트림 처리로 몇 초마다 커밋하는 테이블이 그렇습니다. 스트림 처리는 끝없이 들어오는 데이터를 들어오는 대로 이어서 처리하는 방식입니다.
작은 파일 문제는 파일이 작고 많아져 읽기가 느려지는 문제입니다. 엔진이 여는 파일 수가 그만큼 늘기 때문입니다.
Iceberg 테이블은 이렇게 쌓이는 파일을 치우는 정리 작업을 따로 돌립니다.
| 작업 | 하는 일 |
|---|---|
| 스냅샷 만료 | 정한 기간보다 오래된 스냅샷을 목록에서 빼고, 그 스냅샷만 가리키던 파일을 지운다 |
| 컴팩션 | 작은 데이터 파일 여럿을 큰 파일로 합쳐 다시 쓴다 |
| 고아 파일 삭제 | 쓰다가 실패해 어느 스냅샷도 가리키지 않는 파일을 지운다 |
스냅샷을 만료하면 그 시점으로는 시간 여행을 못 합니다. 스냅샷을 얼마나 오래 남기느냐가 되돌릴 수 있는 기간을 정합니다.
이 작업들을 Iceberg 라이브러리가 스스로 돌리지는 않습니다. 따로 도는 서버가 없기 때문입니다. 엔진으로 주기적으로 부르거나 관리형 서비스에 맡깁니다.
Iceberg 를 고르는 경우
객체 스토리지에 쌓인 분석용 데이터를 여러 엔진이 함께 읽고 쓸 때 맞습니다. Spark 로 적재하고 Trino 로 조회하는 식입니다. 파일이 많아 폴더 목록을 훑는 데만 한참 걸리는 큰 테이블에도 맞습니다.
주문 한 건을 곧바로 읽고 고치는 서비스 데이터베이스 노릇은 못 합니다. 커밋마다 파일 여러 개를 새로 쓰고 카탈로그를 거치기 때문입니다. 그런 일은 PostgreSQL 같은 관계형 데이터베이스가 맡습니다. Iceberg 는 그 데이터를 옮겨 와 분석하는 쪽에 섭니다.
데이터가 데이터베이스 하나에 다 들어가면 Iceberg 를 세울 까닭이 적습니다. 얻는 것보다 카탈로그를 운영하고 정리 작업을 돌리는 일이 더 크게 늘어납니다.
맞물림
Iceberg 는 혼자 테이블이 되지 못합니다. 파일을 읽고 쓰는 엔진, 행을 담는 파일 포맷, 지금 위치를 쥐는 카탈로그가 있어야 합니다. 이 절은 이 셋이 Iceberg 와 어느 방향으로 붙는지 봅니다. 여기 나오는 엔진과 포맷은 Trino 를 빼면 모두 Iceberg 와 같은 Apache 재단의 프로젝트입니다.
엔진이 부르는 Iceberg 라이브러리
Spark, Flink, Trino 같은 엔진이 Iceberg 라이브러리를 불러 씁니다. Flink 는 끝없이 들어오는 데이터를 이어서 처리하는 엔진입니다. 엔진은 SQL 을 받아 무엇을 읽을지 계획을 짭니다. 이때 Iceberg 에게 이 조건에 걸리는 데이터 파일이 무엇인지 묻습니다.
Iceberg 는 매니페스트에 적힌 최솟값과 최댓값으로 파일을 걸러 목록을 돌려줍니다. 엔진은 그 목록의 파일만 엽니다.
기능은 엔진마다 따로 따라옵니다. 행 지우기나 시간 여행 문법을 한 엔진은 받고 다른 엔진은 아직 못 받을 수 있습니다. 여러 엔진이 한 테이블을 쓰면 가장 늦게 따라온 엔진에 맞춰 기능을 골라 씁니다.
Iceberg 가 행을 적는 Parquet 파일
Iceberg 는 행을 바이트로 적는 방법을 새로 만들지 않습니다. 데이터 파일은 흔히 Parquet 으로 적습니다. ORC(Optimized Row Columnar)나 Avro 로 적을 수도 있습니다.
매니페스트와 매니페스트 리스트는 Avro 로 적습니다. Avro 는 행 단위로 적는 이진 파일 포맷입니다. Iceberg 가 이 포맷들의 라이브러리를 불러 파일을 씁니다. 앞에서 본 열 번호도 이때 Parquet 파일 안에 함께 적힙니다.
Parquet 파일은 끝까지 다 쓰고 닫아야 읽을 수 있습니다. 파일 끝에 붙는 요약 정보가 있어야 읽는 쪽이 열을 찾기 때문입니다. 그래서 몇 행씩 자주 쓰면 닫힌 작은 파일이 계속 쌓입니다. 앞의 「쌓이는 파일과 정리」에서 본 컴팩션이 필요한 까닭 하나가 이것입니다.
Iceberg 가 지금 위치를 맡기는 카탈로그
Iceberg 는 커밋할 때 카탈로그를 부릅니다. 이 테이블의 메타데이터 위치를 옛 파일에서 새 파일로 바꿔 달라고 요청합니다. 카탈로그가 해 줄 일은 이 교체를 한 번에 해내는 것 하나입니다.
카탈로그로 쓰이는 것은 여럿입니다. 어느 것을 골라도 맡는 일은 이 교체 하나로 같습니다. 아래 세 문단이 흔히 쓰는 셋입니다.
오래 쓰인 카탈로그는 Hive 메타스토어입니다. 원래 Hive 테이블의 폴더 위치를 적어 두던 데이터베이스입니다. Iceberg 는 그 칸에 메타데이터 파일 위치를 적습니다.
REST(Representational State Transfer)는 HTTP(HyperText Transfer Protocol) 주소와 메서드로 자원을 다루는 방식입니다. 이 방식으로 부르는 REST 카탈로그도 씁니다.
AWS(Amazon Web Services)에서는 AWS Glue 의 데이터 카탈로그가 같은 일을 합니다.
카탈로그가 멈추면 커밋도 멈춥니다. 데이터 파일이 객체 스토리지에 멀쩡히 있어도 새 메타데이터 파일을 가리킬 수 없습니다. 엔진마다 다른 카탈로그를 보면 같은 테이블이 둘로 갈라집니다. 한 테이블을 쓰는 엔진은 모두 같은 카탈로그를 봐야 합니다.
관련 항목
Apache Iceberg 가 속하는 상위 분류
테이블 포맷 · 데이터 레이크 · 레이크하우스 · 데이터 엔지니어링 · 오픈 소스 · Apache Software Foundation
Apache Iceberg 와 같은 역할을 두고 겨루는 테이블 포맷
Delta Lake · Apache Hudi · Apache Paimon · Apache Hive
Apache Iceberg 테이블을 읽고 쓰는 쿼리 엔진
쿼리 엔진 · Apache Spark · Apache Flink · Trino · Amazon Athena · Amazon EMR · Dremio · Snowflake
Apache Iceberg 가 행과 목록을 적는 파일 포맷
Apache Parquet · ORC · Apache Avro · JSON · 열 지향 포맷
Apache Iceberg 테이블의 지금 위치를 쥐는 카탈로그
데이터 카탈로그 · Hive 메타스토어 · REST 카탈로그 · AWS Glue · Apache Polaris · Project Nessie
Apache Iceberg 파일이 놓이는 저장소
객체 스토리지 · Amazon S3 · Google Cloud Storage · Azure Blob Storage · HDFS
Apache Iceberg 메타데이터를 이루는 구성 요소
메타데이터 · 스냅샷 · 매니페스트 · 스키마 · 파티션 · 삭제 파일
Apache Iceberg 가 쓰기에서 지키는 성질
ACID · 원자성 · 커밋 · 스냅샷 격리 · 낙관적 동시성 제어 · MVCC
Apache Iceberg 가 테이블에 더하는 기능
시간 여행 쿼리 · 숨은 파티셔닝 · 파티셔닝 · 스키마 진화 · 쓰기 시 복사 · 읽기 시 병합
Apache Iceberg 테이블에서 자주 나는 운영 문제
작은 파일 문제 · 컴팩션 · 스냅샷 만료 · 고아 파일 · 스트림 처리
다른 이름: Iceberg · 아이스버그 · 아파치 아이스버그