目次
- Apache Iceberg と Delta Lake の違い
- Apache Iceberg のアーキテクチャ
- Delta Lake のアーキテクチャ
- Parquet ファイルとは
- Parquet のクエリ効率
1. Apache Iceberg と Delta Lake の違い
Apache IcebergとDelta Lake(Delta Table)は、どちらもデータレイク上でACID トランザクションやスキーマ進化などを実現するオープンテーブルフォーマットです。
開発元と背景
| 項目 | Apache Iceberg | Delta Lake |
|---|---|---|
| 開発元 | Netflix発、現在はApache財団 | Databricks |
| オープンソース | 完全オープン | オープンソース(一部機能はDatabricks専用) |
アーキテクチャの違い
Iceberg は、メタデータを階層構造(カタログ → メタデータファイル → マニフェストリスト → マニフェストファイル)で管理します。この設計により、大規模データでのクエリプランニングが高速です。
Delta Lake は、トランザクションログ(_delta_logディレクトリ内のJSONファイル)でテーブルの状態を追跡します。チェックポイント機能により、ログの読み込みを最適化します。
主要な機能比較
| 機能 | Iceberg | Delta Lake |
|---|---|---|
| Hidden Partitioning | ✅ パーティション列を隠蔽可能 | ❌ パーティション列が露出 |
| Partition Evolution | ✅ データ書き換え不要 | ⚠️ 制限あり |
| Schema Evolution | ✅ 柔軟(列の追加・削除・リネーム) | ✅ サポート |
| Time Travel | ✅ スナップショットベース | ✅ バージョンベース |
| エンジン互換性 | Spark, Trino, Flink, Hive等 | 主にSpark(他エンジンも対応中) |
選択の指針
Icebergが向いているケース
- マルチエンジン環境(Spark以外も使う)
- ベンダーロックインを避けたい
- パーティション戦略を頻繁に変更する
Delta Lakeが向いているケース
- Databricks環境をメインで使う
- Sparkエコシステムに集中している
- DatabricksのUnity Catalogなど統合機能を活用したい
最近の動向
両フォーマットとも相互運用性が進んでおり、Delta LakeのUniFormやIcebergのDelta Lake互換機能など、境界が曖昧になりつつあります。また、Apache XTableのようなフォーマット変換ツールも登場しています。
2. Apache Iceberg のアーキテクチャ
Apache Icebergは5層構造でメタデータを階層的に管理し、大規模データでも効率的なクエリ実行を実現しています。
構造図
┌─────────────────────────────────────────────────────────┐
│ Icebergカタログ │
│ db1.table1 │
│ 現在のメタデータの位置 │
└─────────────────────┬───────────────────────────────────┘
│
┌─────────────┴─────────────┐
▼ ▼
┌───────────────┐ ┌───────────────┐
│ メタデータ │ │ メタデータ │
│ ファイル s0 │ │ ファイル s1 │
└───────┬───────┘ └───────┬───────┘
│ │
▼ ▼
┌───────────────┐ ┌───────────────┐
│ マニフェスト │ │ マニフェスト │
│ リスト │ │ リスト │
└───────┬───────┘ └───────┬───────┘
│ │
┌────┴────┐ ┌────┴────┐
▼ ▼ ▼ ▼
┌──────┐ ┌──────┐ ┌──────┐ ┌──────┐
│マニフェ│ │マニフェ│ │マニフェ│ │マニフェ│
│ストファ│ │ストファ│ │ストファ│ │ストファ│
│イル │ │イル │ │イル │ │イル │
└───┬──┘ └───┬──┘ └───┬──┘ └───┬──┘
│ │ │ │
▼ ▼ ▼ ▼
┌──────┐ ┌──────┐ ┌──────┐ ┌──────┐
│データ │ │データ │ │データ │ │データ │
│ファイル│ │ファイル│ │ファイル│ │ファイル│
└──────┘ └──────┘ └──────┘ └──────┘
各層の役割
2.1 カタログ(最上位層)
テーブル名(例:db1.table1)から現在有効なメタデータファイルの場所を引くための「台帳」です。
コミット時には、新しいメタデータへの参照(ポインタ)を原子的に更新することで、同時更新を制御し、ACIDトランザクションを保証します。
2.2 メタデータファイル
テーブルの「設計図」に相当します。以下の情報を保持します:
- スキーマ定義
- パーティション仕様
- テーブル設定
- 現在のスナップショットID(どのスナップショットが最新版かを示す)
2.3 マニフェストリスト
あるスナップショットが参照するマニフェストファイルの一覧です。
クエリ計画時に「どのマニフェストを読めばよいか」を素早く絞り込むための索引として機能します。
2.4 マニフェストファイル
データファイル(+削除ファイル)単位の台帳です。各ファイルについて以下を記録します:
- 追加/削除状態
- パーティション値
- 行数・サイズ
- 列統計(min/max/null数など)
この情報により、読み取り時に不要なファイルをスキップする**プルーニング(枝刈り)**が可能になります。
2.5 データファイル(最下位層)
実データ本体で、多くは Parquet / ORC / Avro 形式です。
重要なポイント:Icebergはデータを直接「上書き更新」するのではなく、新しいデータファイルを追加し、参照関係(メタデータ)を切り替えることでテーブル更新を表現します。これがTime Travelやスナップショット分離を可能にする仕組みです。
この設計の利点
| 利点 | 説明 |
|---|---|
| 高速なクエリ計画 | 階層的なメタデータにより、必要なファイルだけを特定 |
| プルーニング | 列統計を使って不要ファイルを読み飛ばし |
| ACID保証 | カタログのポインタ切り替えで原子的コミット |
| Time Travel | 古いスナップショットを参照すれば過去データにアクセス可能 |
3. Delta Lake のアーキテクチャ
Icebergと比較すると、Delta Lakeはよりシンプルな2層構造です。
構造図
Delta Table(例:/path/to/table/)
│
├── _delta_log/ ← トランザクションログ(メタデータ層)
│ ├── 00000000000000000000.json ← バージョン0のログ
│ ├── 00000000000000000001.json ← バージョン1のログ
│ ├── 00000000000000000002.json ← バージョン2のログ
│ ├── ...
│ └── 00000000000000000010.checkpoint.parquet ← チェックポイント
│
└── データファイル群/ ← データ層
├── part-00000-xxxx.parquet
├── part-00001-xxxx.parquet
└── ...
各層の役割
3.1 トランザクションログ(_delta_log)
Icebergの「カタログ+メタデータファイル+マニフェスト」に相当する役割を、JSONログファイルで一元管理します。
| 要素 | 説明 |
|---|---|
| JSONログ | 各コミットの変更内容(追加/削除ファイル、スキーマ変更など)を記録 |
| チェックポイント | 10コミットごとにParquet形式で状態をスナップショット化。ログの読み込みを高速化 |
JSONログの中身の例:
{
"add": {
"path": "part-00000-xxxx.parquet",
"size": 1024000,
"partitionValues": {"date": "2025-01-01"},
"stats": "{\"numRecords\":10000,\"minValues\":{\"id\":1},\"maxValues\":{\"id\":10000}}"
}
}
3.2 データファイル
Icebergと同様、Parquet形式が主流です。データ本体を格納します。
Iceberg vs Delta Lake:アーキテクチャ比較
| 観点 | Iceberg | Delta Lake |
|---|---|---|
| メタデータ構造 | 5層(カタログ→メタデータ→マニフェストリスト→マニフェスト→データ) | 2層(トランザクションログ→データ) |
| メタデータ形式 | Avro/JSON(階層的) | JSON + Parquetチェックポイント |
| 状態管理 | スナップショットID切り替え | ログの連番管理 |
| プルーニング情報 | マニフェストファイルに列統計 | JSONログのstatsフィールド |
| カタログ | 外部カタログ必須(Hive, Glue等) | 不要(_delta_logが自己完結) |
Delta Lakeの設計思想
シンプルさ優先:ディレクトリ1つで完結するため、セットアップが簡単です。_delta_logフォルダさえあれば、どこでもDelta Tableとして認識されます。
トレードオフ:
- ✅ 導入が容易、Sparkとの親和性が高い
- ⚠️ 大規模テーブル(数百万ファイル)ではログ読み込みがボトルネックになりやすい
- ⚠️ マルチエンジン対応はIcebergより限定的(改善中)
4. Parquet ファイルとは
Parquetは、ビッグデータ処理に最適化された列指向(カラムナ)形式のファイルフォーマットです。Apache Software Foundationが開発し、Spark、Hive、Prestoなど多くのツールで標準的に使われています。
行指向 vs 列指向
【元のデータ】
| id | name | age |
|-----|---------|-----|
| 1 | Alice | 25 |
| 2 | Bob | 30 |
| 3 | Charlie | 28 |
【行指向(CSV等)】 【列指向(Parquet)】
1, Alice, 25 id: [1, 2, 3]
2, Bob, 30 name: [Alice, Bob, Charlie]
3, Charlie, 28 age: [25, 30, 28]
Parquetの特徴
4.1 列単位でデータを格納
必要な列だけを読み込めるため、「全100列のうち3列だけ欲しい」といった分析クエリが高速になります。
4.2 高い圧縮率
同じ列には似た値が並ぶため、圧縮アルゴリズム(Snappy, Gzip, Zstd等)が非常に効きます。CSVと比べて1/10以下のサイズになることも珍しくありません。
4.3 スキーマ埋め込み
ファイル自体にスキーマ情報(列名・型)が含まれているため、別途定義ファイルが不要です。
4.4 列統計の保持
各列のmin/max値やnull数を保持しており、クエリ時の**プルーニング(読み飛ばし)**に活用されます。
ファイル形式の使い分け
| 形式 | 向いている用途 |
|---|---|
| CSV | 人間が読む、簡単なデータ交換 |
| JSON | 半構造化データ、APIレスポンス |
| Parquet | 大規模データ分析、データレイク |
| Avro | ストリーミング、スキーマ進化が多い場合 |
具体例:読み込み速度の違い
# 100列 × 1億行のデータから3列だけ取得する場合
# CSV: 全データを読んでから3列抽出 → 遅い
df = spark.read.csv("data.csv").select("id", "name", "age")
# Parquet: 最初から3列分だけ読む → 速い
df = spark.read.parquet("data.parquet").select("id", "name", "age")
5. Parquet のクエリ効率
Parquetは分析系クエリで効率が良いという特性があります。
Parquetが効率的なケース
列の絞り込みがあるクエリ
-- 100列あるテーブルから3列だけ取得
SELECT id, name, age FROM users WHERE age > 25
Parquetはid、name、ageの3列分だけ読み込みます。CSVだと全100列を読んでから捨てることになります。
集計・分析クエリ
SELECT AVG(salary), MAX(salary) FROM employees
salary列だけを連続して読めるため、CPUキャッシュ効率も良くなります。
Parquetが不向きなケース
1行まるごと取得するクエリ
SELECT * FROM users WHERE id = 12345
行指向形式なら1箇所を読めば済みますが、Parquetは各列のブロックを横断して読む必要があります。
頻繁な1行単位の更新・挿入
Parquetは追記や書き換えに向いていません。OLTPデータベース(MySQL、PostgreSQL等)の方が適しています。
効率性まとめ
| 用途 | Parquetの効率 |
|---|---|
| 大量データの集計・分析 | ◎ 非常に良い |
| 特定列だけ読むクエリ | ◎ 非常に良い |
| 全列を読むクエリ | △ 普通 |
| 1行単位のランダムアクセス | ✗ 不向き |
| 頻繁な更新・削除 | ✗ 不向き |
つまり、OLAP(分析)には強く、OLTP(トランザクション処理)には弱いという特性があります。データレイクやDWHで使われるのはこのためです。
まとめ
| 技術 | 役割 | 特徴 |
|---|---|---|
| Apache Iceberg | テーブルフォーマット | 5層構造、マルチエンジン対応、パーティション進化に強い |
| Delta Lake | テーブルフォーマット | 2層構造、シンプル、Spark/Databricksとの親和性 |
| Parquet | ファイルフォーマット | 列指向、高圧縮、分析クエリに最適 |
これらの技術は組み合わせて使われることが多く、IcebergやDelta Lakeのデータ層にはParquetファイルが採用されるのが一般的です。