🏔️
概念 #データ設計 #Lakehouse #Apache Iceberg #Delta Lake #データレイク #DDIA 📚 データ志向アプリケーション設計(DDIA)

Lakehouse(Apache Iceberg / Delta Lake)

データレイクとDWHを統合する次世代アーキテクチャ。Apache IcebergとDelta Lakeの設計思想、ACID保証・スキーマ進化・タイムトラベルの仕組みを理解する

定義

Lakehouse:データレイク(安価・柔軟)とデータウェアハウス(ACID・高性能クエリ)の利点を統合したアーキテクチャ。S3などのオブジェクトストレージの上にトランザクション層を追加することで実現する。

データレイクとDWHの問題

データレイク(S3 + Parquet)の問題:
  ✅ 安価・無限にスケール
  ✅ あらゆる形式のデータを保存できる
  ❌ ACIDがない(ファイルを上書きする操作が中断されたら壊れる)
  ❌ スキーマ変更が難しい
  ❌ 古いファイルが溜まる(デリートが困難)
  ❌ 「最新のデータがどのファイルか」管理が大変

データウェアハウス(BigQuery, Snowflake)の問題:
  ✅ ACID保証・高速クエリ
  ✅ スキーマ管理が容易
  ❌ ベンダーロックイン
  ❌ 生データ(画像・音声・非構造化)を扱えない
  ❌ DWHへのコピーで二重管理・鮮度の問題

Lakehouse:
  S3等のオブジェクトストレージを「そのまま」使いながら
  DWHと同等のACID・スキーマ管理・高速クエリを実現

Apache Icebergの設計

Netflixが開発し、ApacheトップレベルプロジェクトになったLakehouseフォーマット。

メタデータ層の構造

S3バケット
  ├── data/
  │   ├── part-00001.parquet
  │   ├── part-00002.parquet
  │   └── ...(実際のデータファイル)

  └── metadata/
      ├── v1.metadata.json    ← テーブルのスキーマ・スナップショット一覧
      ├── v2.metadata.json    ← 更新のたびに新しいバージョン
      ├── snap-001.avro       ← スナップショット(ファイルリスト)
      └── snap-002.avro

スナップショットベースのACID

書き込みフロー:
  1. 新しいParquetファイルをS3に書く(アトミック操作)
  2. 新しいメタデータファイルを作成(変更リスト)
  3. current-metadata-location をアトミックに更新
     → これがコミット操作

読み取りフロー:
  1. current-metadata-location を読む
  2. 最新のスナップショットのファイルリストを取得
  3. そのファイルだけ読む

中断した書き込み:
  新しいParquetファイルは書かれているが、
  メタデータが更新されていない
  → 誰にも見えないゴミファイルとして残る(定期的にorphan fileを掃除)
  → 読み取り側には全く影響なし

タイムトラベル(Time Travel)

-- Sparkでの例(SparkはIcebergをネイティブサポート)

-- 1時間前のデータを参照
SELECT * FROM catalog.db.orders
TIMESTAMP AS OF '2024-01-15 10:00:00';

-- スナップショットIDで参照
SELECT * FROM catalog.db.orders
VERSION AS OF 12345678;

-- 変更履歴の確認
SELECT * FROM catalog.db.orders.history;

用途:誤ってデータを削除した場合の復元、A/Bテストの再現、監査。

スキーマ進化

# PythonでIcebergのスキーマを変更
from pyiceberg.catalog import load_catalog

catalog = load_catalog('default')
table = catalog.load_table('db.orders')

# カラム追加(後方互換性あり)
with table.update_schema() as update:
    update.add_column('discount_amount', DoubleType())

# カラムリネーム
with table.update_schema() as update:
    update.rename_column('old_name', 'new_name')

# カラム削除(ファイルは変更しない、メタデータのみ)
with table.update_schema() as update:
    update.delete_column('deprecated_field')

Delta Lake

DatabricksがApache Spark向けに開発。Icebergとほぼ同等の機能を持つ。

# PySpark + Delta Lake
from delta.tables import DeltaTable
from pyspark.sql import SparkSession

spark = SparkSession.builder \
    .config('spark.sql.extensions', 'io.delta.sql.DeltaSparkSessionExtension') \
    .getOrCreate()

# Delta Tableへの書き込み
df.write.format('delta').save('s3://bucket/orders')

# UPSERTの例(Delta Lakeの特徴)
deltaTable = DeltaTable.forPath(spark, 's3://bucket/orders')
deltaTable.alias('target').merge(
    updates.alias('source'),
    'target.order_id = source.order_id'
).whenMatchedUpdateAll() \
 .whenNotMatchedInsertAll() \
 .execute()

# タイムトラベル
df_old = spark.read.format('delta') \
    .option('timestampAsOf', '2024-01-15') \
    .load('s3://bucket/orders')

Apache Hudi

MergeOnRead(更新を差分として保存)とCopyOnWrite(更新時にファイルをコピー)の2モードを持つ。Uber発。

3フォーマットの比較:
              Iceberg  Delta Lake  Hudi
ACIDトランザクション  ✅      ✅         ✅
タイムトラベル        ✅      ✅         ✅
スキーマ進化          ✅      ✅         ✅
UPSERT効率          普通     普通       高い(MoR)
エンジンサポート     広い     Spark中心  普通
コミュニティ         活発     活発       普通
採用実績            Netflix等 Databricks Uber等

モダンLakehouseスタック

データソース
  ↓ Fivetran / Airbyte(EL)
S3 / GCS / ADLS(ストレージ)
  ↓ Apache Iceberg / Delta Lake(トランザクション層)
  ↓ dbt(変換)
Spark / Trino / DuckDB(クエリエンジン)

BI ツール(Tableau / Metabase)

Trino(Presto後継):Iceberg/Delta Lakeをクエリできる分散SQLエンジン。BigQueryやSnowflakeに依存せず、自前のLakehouseを構築できる。

関連概念

出典・参考文献

  • Apache Iceberg Documentation — iceberg.apache.org/docs
  • Delta Lake Documentation — docs.delta.io
  • Ryan Blue et al., “Apache Iceberg: An Architectural Look Under the Covers” (2020)
  1. 1. 🗄️データ志向アプリケーション設計:概要
  2. 2. 🧩データモデルとクエリ言語
  3. 3. 💾ストレージエンジンとインデックス
  4. 4. 🔁レプリケーション
  5. 5. 🍕パーティショニング(シャーディング)
  6. 6. 🔒トランザクションとACID
  7. 7. 分散システムの本質的な問題
  8. 8. 🤝一貫性と分散合意
  9. 9. 📦バッチ処理
  10. 10. 🌊ストリーム処理
  11. 11. 📋エンコーディングとスキーマ進化
  12. 12. 🔗Sagaパターンと分散トランザクション
  13. 13. 🏗️データシステムの統合設計
  14. 14. 📸MVCC(多版型同時実行制御)
  15. 15. 📊列指向ストレージとOLAP設計
  16. 16. 🕰️ベクタークロックと因果順序
  17. 17. 🔀CRDT(競合なし複製データ型)
  18. 18. 🔍クエリオプティマイザーと実行計画
  19. 19. キャッシュ戦略とRedis設計
  20. 20. 🔎全文検索と転置インデックス
  21. 21. 🌐NewSQL(分散ACIDデータベース)
  22. 22. 📝WALと論理レプリケーション
  23. 23. 🔌コネクションプーリング
  24. 24. 🚧ゼロダウンタイムマイグレーション
  25. 25. 🆔分散ID生成
  26. 26. 🔄N+1問題とDataLoaderパターン
  27. 27. 📈タイムシリーズDB
  28. 28. 🛡️Row Level Security(行レベルセキュリティ)
  29. 29. 📤Outboxパターン(トランザクショナルアウトボックス)
  30. 30. 💾DBバックアップとPITR
  31. 31. ⚠️データベース設計アンチパターン
  32. 32. 🕸️グラフDB深掘り
  33. 33. 🔋バックプレッシャーとサーキットブレーカー
  34. 34. 🔵コンシステントハッシング
  35. 35. 📋マテリアライズドビュー
  36. 36. 📡DBモニタリングとオブザーバビリティ
  37. 37. 🔐データプライバシーとCrypto-Shredding
  38. 38. ✂️垂直分割(Vertical Partitioning)
  39. 39. 🪟ウィンドウ関数
  40. 40. 🧲ベクトルDBとpgvector
  41. 41. 🔧dbtとデータ変換パイプライン
  42. 42. 📬ジョブキューの設計
  43. 43. 📐正規化理論(1NF〜BCNF)
  44. 44. ☁️クラウドDBサービスの設計思想と選択基準
  45. 45. 🗺️地理空間データとPostGIS
  46. 46. 🔑DBセキュリティと権限管理
  47. 47. 🏔️Lakehouse(Apache Iceberg / Delta Lake)
  48. 48. 📜データコントラクト
  49. 49. 🔭OpenTelemetryとDBトレーシング

出典: Martin Kleppmann, 'Designing Data-Intensive Applications' (2017) Chapter 10 / Apache Iceberg Documentation