Delta Lakeへのワークロード移行ガイド

[Migration guide \| Databricks on AWS](https://docs.databricks.com/delta/porting.html) [2022/4/6時点]の翻訳です。

> [Databricksクイックスタートガイド](https://qiita.com/taka_yayoi/items/125231c126a602693610)のコンテンツです。

:::note warn
本書は抄訳であり内容の正確性を保証するものではありません。正確な内容に関しては原文を参照ください。
:::

ワークロードをDelta Lakeに移行する際、Apache SparkやApache Hiveによっって提供されるデータソースと比較した以下のシンプルさと差異に注意する必要があります。

Delta Lakeは以下のオペレーションを自動でハンドリングするので、皆様が手動で実行すべきではありません。

- **`REFRESH TABLE`**: Deltaテーブルは常に最新の状態の情報を返却するので、変更後に手動で`REFRESH TABLE`を実行する必要はありません。
- **パーティションの追加、削除**: Delta Lakeはテーブルに存在するパーティションセットを自動で追跡し、データが追加、削除されるとデータの一覧を更新します。このため、`ALTER TABLE [ADD|DROP] PARTITION`や`MSCK`を実行する必要はありません。
- **単一パーティションのロード**: 最適化として、例えば`spark.read.parquet("/data/date=2017-01-01")`を実行して、興味のあるデータのパーティションを直接ロードすることがあるかもしれません。Delta Lakeでは、適切なデータを検索するためにトランザクションログからクイックにファイルの一覧を読み込みめるので、これは不要となります。単一のパーティションに興味があるのであれば、`spark.read.delta("/data").where("date = '2017-01-01'")`のように`WHERE`句を使って指定します。パーティション内に大量のファイルがある大規模テーブルにおいては、ディレクトリ内のファイル一覧の取得は、通常はトランザクションログからのファイル一覧取得よりも遅いため、単一のパーティションをロードする(パーティションパスの直接指定、`WHERE`の使用)よりもはるかに高速になる場合があります。

既存のアプリケーションをDelta Lakeに移植する際、トランザクションログをバイパスする以下のオペレーションは避けるべきです。

- **手動でデータを編集**: Delta Lakeはテーブルに対する変更を原子的にコミットするためにトランザクションログを使用します。ログは信頼できる情報源(source of truth)であるため、書き込まれたがトランザクションログに追加されていないファイルはSparkで読み込むことができません。同様に、手動でファイルを削除したとしても、ファイルへのポインターは依然としてトランザクションログに存在します。Deltaテーブルに格納されているファイルを手動で編集するのではなく、このガイドで説明されているコマンドを常に使用してください。
- **外部リーダー**: Delta Lakeに格納されているデータを直接読み込みます。Deltaテーブルの読み込み方に関しては、[Access Delta tables from external data processing engines ](https://docs.databricks.com/delta/integrations.html)をご覧ください。

# サンプル

`/data-pipeline`というディレクトリにParquetデータを格納しており、`events`というDeltaテーブルを作成するものとします。

[最初のサンプル](#deltaテーブルとして保存)では以下の手順を説明しています。

- オリジナルの場所`/data-pipeline`のParquetデータをデータフレームに読み込みます。
- データフレームのコンテンツを別の場所`/tmp/delta/data-pipeline/`にDeltaフォーマットとして保存します。
- `/tmp/delta/data-pipeline/`にあるデータをベースとして`events`テーブルを作成します。

[2つ目のサンプル](#deltaテーブルへの変換)では、格納場所`/data-pipeline/`を変えずにParquetからDeltaフォーマットにデータを変換するために`CONVERT TO TABLE`の使用方法を説明します。

これらの例では、データを指定された場所で管理し続ける[アンマネージドテーブル](https://qiita.com/taka_yayoi/items/e7f6982dfbee7fc84894#%E3%83%9E%E3%83%8D%E3%83%BC%E3%82%B8%E3%83%89%E3%82%A2%E3%83%B3%E3%83%9E%E3%83%8D%E3%83%BC%E3%82%B8%E3%83%89%E3%83%86%E3%83%BC%E3%83%96%E3%83%AB)を作成します。Databricksはメタストアにテーブル名と指定された場所を記録します。

## Deltaテーブルとして保存

1. Parquetデータをデータフレームに読み込み、データフレームのコンテンツを新規ディレクトリに`delta`フォーマットで保存します。

    ```py:Python
    data = spark.read.parquet("/data-pipeline")
    data.write.format("delta").save("/tmp/delta/data-pipeline/")
    ```

1. 新規ディレクトリにあるファイルを参照する`events`というDeltaテーブルを作成します。

    ```py:Python
    spark.sql("CREATE TABLE events USING DELTA LOCATION '/tmp/delta/data-pipeline/'")
    ```

## Deltaテーブルへの変換

ParquetテーブルをDeltaテーブルに変換するオプションは3つあります。

- ファイルをDelta Lakeフォーマットに変換し、Deltaテーブルを作成します。

    ```sql:SQL
    CONVERT TO DELTA parquet.`/data-pipeline/`
    CREATE TABLE events USING DELTA LOCATION '/data-pipeline/'
    ```

- Parquetテーブルを作成し、Deltaテーブルに変換します。

    ```sql:SQL
    CREATE TABLE events USING PARQUET OPTIONS (path '/data-pipeline/')
    CONVERT TO DELTA events
    ```

- ParquetテーブルをDeltaテーブルに変換します。

    ```sql:SQL
    CONVERT TO DELTA events
    ```

    ここでは`events`テーブルがParquetテーブルであると想定しています。

詳細に関しては、[ParquetテーブルをDeltaテーブルに変換する](https://qiita.com/taka_yayoi/items/152a31dc44bda51eeecd#parquet%E3%83%86%E3%83%BC%E3%83%96%E3%83%AB%E3%82%92delta%E3%83%86%E3%83%BC%E3%83%96%E3%83%AB%E3%81%AB%E5%A4%89%E6%8F%9B%E3%81%99%E3%82%8B)をご覧ください。

### Databricks 無料トライアル

[Databricks 無料トライアル](https://databricks.com/jp/try-databricks)