Iceberg 誕生の歴史と概要

# この記事について

毎週木曜の朝に開催している #データエンジニアRadio 第15回のネタとして、Oreilly から発売された Apache Iceberg - The Definitive Guide の第1章を要約したものです。

:::note
この形式で書かれている部分は、私の感想・コメントなどです。
:::

本文は逐語訳でもなければ、必ずしも順番どおりに要約しているわけでもないので、細かい部分も正確に知りたい方は原書をお読みください！

## 本

https://www.amazon.co.jp/dp/1098148622

## データエンジニアRadio

https://qiita.com/IQ_Bocchi/items/d38db751388b10870ab2

# 要約

データレイクハウスの本質は、「データをどう持つか」と「データをどう計算するか」を分離することにある。

:::note
「データレイクハウスはデータウェアハウスとデータレイクのいいとこどり」という雑な説明を受けてきた私にとって、ストレージと計算の分離がデータレイクハウスの本質というこの説明はちょっと目から鱗でした。
第一章を読んで、その言わんとしていることがだいぶ理解できました。
:::

:::note
ちなみに「レイクハウス」というのはウエアハウスとレイクを適当にくっつけた造語ではなく、名前のとおり湖の上に浮かぶ家で、そこから湖の魚を釣ったり、ボートを漕ぎ出したりできるもの。
:::

https://town-n-country-living.com/ultimate-lake-house.html

https://www.lakehouse.team/

https://blog.451alliance.com/data-lakehouse-is-here-to-stay-no-matter-what-we-call-it/

## なぜ Iceberg が必要となったのかを、歴史を通じて理解する

### OLTP の登場

一般的なデータベースといえば、 RDBMS。データをテーブル形式で持つDBで、リアルタイムな取引の記録にはこれが使われる。

たくさんのユーザーによる取引を支えるシステムを、OnLine Transaction Processing - OLTPという。

OLTPには本番業務でのユーザーの取引や動きが記録されているので、このデータを **分析して活用したい** というニーズが発生した際に、OLTPには以下のような限界があった。

| # | 問題点 | なぜ困る？ |
|:-|:-|:-|
|1 |OLTPは**個々の行を処理する**のに適したデータの持ち方をしている（**行指向**）| 分析用途では、全ユーザーの取引情報を **集計** するニーズが高いため、**列指向**の方がパフォーマンスがいい|
|2 |リソースの競合 |本番のデータベースを分析用に使った結果、本番業務のデータ処理のパフォーマンスが落ちるみたいなことがあっては困る|
|3 |OLTPでは、同じデータを重複させないために、テーブルを[**正規化**](https://oss-db.jp/dojo/dojo_info_04)する|正規化をすると、データを利用するときにテーブルを結合する処理が発生する。大量になると、結合によるパフォーマンスの下がりが顕著になるため、データを**非正規化**して持っておきたいニーズがある。|

:::note
2のリソース競合については、本番処理が「ちょっと重くなる」くらいのレベルならいいのですが、重い集計を走らせると本番業務が止まってしまうこともあるので大きな問題。
:::

https://qiita.com/glassmonkey/items/774bf3dd84ae2488dea2

このようなOLTPの限界への対応として、本番業務のシステムとは別に分析系のシステムを持つという OLAP - OnLine Analytical Processing という考え方が登場する。

:::note
OLTP と OLAP を区別する考え方は現在でも主流ではありますが、データ活用がビジネスの根幹に関わるという認識が広まったことや、コンピューターの性能向上に伴い「本番系と分析系って、ほんとに区別するのがあるべき姿なんだっけ？」という議論もあります。
[#データエンジニアRadio の 過去回](https://x.com/i/spaces/1MYxNopaQgNKw)で、そのあたりの話を中心に扱った回もあるので興味のある方は聞いてみてください✨
:::

### OLAP と データウェアハウス

OLAP を支えるシステムとして、人気になったのがデータウェアハウス。

#### OLAPの構成要素

技術的に見ると、OLAPは以下の要素で構成されている。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587845/1ed4acc4-1e05-7eef-103c-48311272b442.png)

##### ストレージ

ローカルのファイルシステムのほか、HDFSなどの分散ファイルシステムや、S3のようなクラウドのオブジェクトストレージなどがここにあたる。

この層にデータベースを置く場合は、行指向のデータベースを使うこともできるが、列指向のデータベースの方が優勢。

##### ファイルフォーマット

構造化データ（CSVなど）と半構造データ（JSONなど）に大別される。
構造化データはさらに、行指向のファイルフォーマット（CSV、AVRO）と列指向のファイルフォーマット（ORC、PARQUET）に分かれる。

:::note
AVRO, ORC, PARQUET はいずれも、独自のデータの圧縮形式を持ち、データをデータ部分とスキーマ部分に分けて保持することで、一定のスキーマを担保しながら効率よくデータを処理できるファイル形式という理解！
:::

##### テーブルフォーマット

データのテーブルとしての構造を決めるレイヤ。
ファイルフォーマット上のメタデータのようなもので、データファイルがどのようにストレージ上にレイアウトされるべきかを司る。

##### ストレージエンジン

データをストレージ上に物理的にレイアウトしたり、物理的な最適化、インデックスの管理などを実際に行う。

##### カタログ

計算エンジンとユーザーは、ここを参照することで、どんなテーブルがあるか、テーブルの名前やスキーマなどを知ることができる。

##### 計算エンジン

ユーザーの求めに応じて計算の処理（データの集計など）を実際に行う。

#### データウエアハウスのアプローチ

上記の構成要素を、以下のように組み合わせたのがデータウエアハウス。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587845/63e33e69-4d00-0bcf-fc08-39dffbc4368f.png)

:::note
データウエアハウスは、つまるところ、大量のデータを持っているデータベース。なのでデータウエアハウスのデータを利用するときは、データウエアハウスとして使われているDBに対してクエリ（SQL）を投げることになる。
DBの中でデータが物理的にどう保たれているかをユーザーが意識することはないし、物理的なデータに直接アクセスすることもない。
すべて**DBが提供する形式のクエリを通じて処理する**ことになるわけだが、上記の図で **ユーザーからの矢印がすべて Compute engine (計算エンジン)に集約されている**　のはそういうこと。
:::

このアプローチには長所と短所がある。

- 長所
    - 唯一の真実の源泉として、様々なソースからのクエリを受け付けられる
    - 大量の分析データを素早く処理できる
    - データのガバナンスを効かせやすい
    - クエリに最適化されたデータのレイアウトを保証できる
    - データがスキーマに適合していることを保証できる
- 短所
    - データウエアハウス内のデータはデータウエアハウスのベンダー固有のデータ形式で持っており、**そのデータウエアハウスの計算エンジンを通じてしかアクセスできない**
    - 高え（お金が）
    - 基本的に、構造化データにしか対応していない
    - 機械学習のようなワークロードをネイティブにサポートしていない

##### 機械学習とデータウエアハウス

データウエアハウスはつまるところデータベースなので、データウエアハウス上で機械学習などの計算処理を実行できるわけではない。

そのため、データウエアハウスのデータ使って機械学習のモデルを作りたい場合は、データウエアハウスにクエリをかけて必要なデータを取り出して、そのデータを機械学習のモデルを作るためのプラットフォームにコピーして持っていく必要がある。

そうすると、機械学習に使うデータと実際のデータがズレたり、それによってモデルが使い物にならなくなったりする。

データのクエリ、転送にかかる計算やネットワークのコスト、コピーしたデータを持っておくためのストレージのコストもばかにならない。

### データレイク

そこで、データレイクの登場です。先ほどのOLAPの構成要素が、データレイクでは以下のように位置づけられる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587845/9a30584e-0901-4df7-fc8e-27f276d17d6b.png)

データウエアハウスでは、ストレージやファイルフォーマットの層にあったのは「そのデータウエアハウスに固有の形式」だったが、データレイクでは、ストレージにはHDFSやS3などの様々な種類を選べるし、そこにどういうファイル形式のデータを置いてもいい。

ストレージに置いてあるデータには、MapReduceのようなプログラムを介してアクセスしてもいいし、HiveのようなSQLエンジンを使ってアクセスしてもいい。

:::note
Map Reduce と Hiveの歴史についても、[#データエンジニアRadio の過去回](https://togetter.com/li/2354445) でお話しているのでぜひ聞いてください！
:::

データレイクをデータウエアハウスから分かつ特徴は、**異なるワークロードに対して、異なる計算のエンジンを使えることだ**。

:::note
ここも目から鱗ポイントのひとつでした。
JTC在籍時代に聞いていたのは「分析用のデータをテーブル形式で持つのがデータウエアハウス」「どんな形式のデータでもとりあえず突っ込んでおけるのがデータレイク」という説明だった。
:::

#### データレイクの長所と短所

しかしデータレイクも万能ではなく、以下のような長所と短所がある。

- 長所
    - コストが低い
    - データの形式が自由である
    - 非構造のデータを扱える
- 短所
    - パフォーマンス
        - データウエアハウスは内部に独自の最適化の仕組みを持っているが、データレイクではそこが作る人の腕次第になってしまう。
    - 設定が複雑
        - データの形式が自由なだけに、最適化のレベルなども使う側が設定する必要があるため
    - [ACID](https://e-words.jp/w/ACID%E7%89%B9%E6%80%A7.html)を保証していない

### データレイクハウス

データウエアハウスとデータレイクには、それぞれ長所と短所がある。
データウエアハウスにはないデータレイクの長所を活かしつつ、データレイクの限界を突破するために登場したのがデータレイクハウスであり、その根幹をなすのがテーブルフォーマットである。

#### データレイクハウスが目指すもの

データレイクハウスは、以下のような価値を実現する。

- データのコピーを減らす
- クエリのスピードを上げる
- 過去のデータのスナップショットを持つ
- 価格が抑えられる
- アーキテクチャがオープンである

データレイクハウスにおいて、OLAPに必要な技術要素は以下のように位置付けられる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587845/14e5ae18-3789-365f-c119-57c3aca0dea6.png)

データレイクの上に自由にデータを置きながら、オペレーションは厳密に行うというのがデータレイクハウスのアーキテクチャである！

### テーブルフォーマットとは

テーブルフォーマットとは、複数のデータファイルを統合されたひとつのテーブルとして扱うための仕組みのことだ。

#### HMS の限界とその原因

データレイク上のデータをテーブルとして扱うためのテーブルフォーマットとして、最初に登場したのが Hive metastore = HMS だった。

そもそも（物理的なデータの持ち方と、論理的なスキーマを分離できる）テーブルフォーマットを初めて実現したという点で HMS の貢献は大きかった。

:::note
HMS は、もともとは Hive というクエリエンジンが使うためのメタデータ管理の仕組みとして作られた。その後、様々なクエリエンジンが登場したが、Hive以外のクエリエンジンもテーブルフォーマット部分は HMS に依存しているケースが多く、そういう意味でも影響力が大きいといえるでしょう。
:::

しかし現在では、HMS の抱える様々な制約・限界が顕在化してきており、**その制約・限界はすべて、HMS がテーブルをディレクトリの単位でしか認識しないという根本原因に由来する**。

:::note
この章最大の aha-moment (アハ体験) !!!
:::

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587845/73fea93d-8de7-8224-5498-62c4dade2bf6.png)

## Iceberg

上記の HMS の限界を、 **ファイル単位**でデータを管理することにより突破しようとするのが **Iceberg** である！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/587845/5757070f-b4b8-e500-9030-4965ef9f0e7b.png)

:::note
- HMS の場合
    - HMSが直に各ディレクトリを見に行っている
    - ディレクトリ単位での管理しかできない
- Iceberg (Iceberg catalog) の場合
    - Iceberg catalog が直接見ているのは（最新世代の）メタデータファイルのみ
    - 最終的には個々のデータファイルにまで管理が及ぶ
:::

メタデータファイル、マニフェストリスト、マニフェストファイルの役割については、第5章で詳述するから楽しみにしていてくれよな！

### Iceberg が突破する HMS の限界

上記のアーキテクチャにより、 Iceberg が HMS より良くなるのは、具体的には以下のポイント。
これらを可能にするアーキテクチャの詳細は、第2章で詳述。

#### ACID トランザクションのサポート

HMS　では、単一のディレクトリ単位での Atomicity は担保できたが、複数のパーティションにまたがる Atomicity が担保できなかった。

Iceberg は、データファイルやそこに紐づくマニフェストファイル、マニフェストリストの変更が完了した時点でメタデータファイルの世代を切り替えるという仕組みにより、トランザクション全体の Atomicity が担保される。

#### パフォーマンスの向上

HMS では、実際のクエリ結果に不要なファイルも含めて全ファイルをスキャンして実行計画を立て、その実行計画に基づいてクエリを実行する。この点が、実行計画を立てるのと、実行自体の両方のボトルネックになっていた。

Iceberg は マニフェストファイルとメタデータファイルにより、この問題を解決する。

#### ユーザーがパーティションを意識する必要がない

HMS では、テーブル設計時にパーティションを区切っても、ユーザーがパーティションとなっている行を意識的に使ってその行でフィルターをかけない限り、パーティションによるパフォーマンス向上の効果が得られない。

Iceberg　では、どこの行でパーティションを区切っているかをユーザーが意識しなくても、パーティションによるパフォーマンス向上の恩恵を得られる。

#### パーティションをあとから変更できる（Partition Evolution）

HMS では、パーティションはテーブル作成時にしか指定できなかったため、パーティションを変えたければテーブルを作り直すしかなかった。

Iceberg は、テーブル作成後にパーティションを変更できる。

#### スキーマをあとから変更できる（Schema Evolution）

テーブルの列をあとから追加したり、削除したり、列名を変えたり、その列に入るデータの型を変えたりすることも、Iceberg ではテーブル作成後にできる。

:::note warn
HMS ではこれができない？ 部分的にしかできない？？　（要調査）
→ 回答いただきました！（下記ツイート参照）
:::

https://x.com/ebyhr/status/1801099425458397354

:::note alert
Hive でも Alter table はできる。
ただし、パーティションの保護モードを無視してパーティションカラムのメタデータを書き換えてしまう文法もあり、注意して使ってくれよな！ という旨が公式ドキュメントに書いてある。
:::

#### 行レベルのテーブル操作

HMS が苦手としていた行レベルのデータの変更を、Iceberg は以下の2つの方式でサポートする。

- COW - Copy On Write
    - 変更対象の行が含まれるファイル全体を、書き込みのタイミングで書き換える

- MOR - Merge On Read
    - 変更対象の行の情報だけを持つファイルを作成し、読み込みのタイミングですべてのファイル情報をマージする

:::note
上記の方式から明らかなように、COWは読みは速いが書きが遅く、MORは書きは速いが読みに時間がかかる。
どちらが良いかはユースケースによる。
:::

#### スナップショットによるタイムトラベルとバージョンロールバック

Iceberg はメタデータファイルのバージョン切り替えにより、過去のある時点のデータを再現してクエリしたり、過去の任意の時点へのデータの切り戻し（バージョンロールバック）を行うことができる

:::note
上記はその時点のデータのスナップショットをとっておいていることが前提だが、当然スナップショットを保存している分だけデータ量は多くなる。不要なスナップショットは削除することがベストプラクティスだそうです。（社内研修より）
:::


# 最後に

ここまで記事をお読みいただき、ありがとうございました！
せっかく読んだことだし、この本の翻訳プロジェクトが発足した際にはぜひ参加したいです。

Iceberg コミュニティの皆様、よろしくお願いいたします。