Unity Catalogにおけるボリュームの作成

[Create volumes \| Databricks on AWS](https://docs.databricks.com/data-governance/unity-catalog/create-volumes.html) [2023/7/12時点]の翻訳です。

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

:::note info
**プレビュー**
本機能は[パブリックプレビュー](https://docs.databricks.com/release-notes/release-types.html)です。
:::

本書では、Unity Catalogにおける*ボリューム*のコンセプトを紹介し、ボリュームの作成方法を説明します。

# Unity Catalog volumesとは？

ボリュームは、クラウドオブジェクトストレージロケーションのストレージの論理的ボリュームを表現するUnity Catalogのオブジェクトです。ボリュームは、ファイルのアクセス、格納、制御、整理する能力を提供します。テーブルは表形式のデータセットに対するガバナンスを提供しますが、ボリュームは非テーブルケー式のデータセットに対するガバナンスを追加します。構造化、半構造化、非構造化データを含むすべてのフォーマットのファイルの格納、アクセスを行うためにボリュームを活用することができます。

# マネージドボリュームとは？

**マネージドボリューム**は、スキーマを格納するデフォルトストレージロケーションに作成されるUnity Catalog管理のストレージボリュームです。マネージドボリュームによって、外部ロケーションやストレージ資格情報のオーバーヘッドなしに、ファイル操作のための管理されたストレージを作成することができます。マネージドボリュームを作成する際にロケーションを指定する必要はなく、マネージドボリュームのデータに対するすべてのファイルアクセスは、Unity Catalogによって管理されるパスを通じて行われます。[ボリュームのファイルへのアクセスに使われるパスは？](#ボリュームのファイルへのアクセスに使われるパスは)をご覧ください。

マネージドボリュームを削除すると、30日以内にボリュームに格納されているファイルもクラウドテナントから削除されます。

# 外部ボリュームとは？

**外部ボリューム**は、Unity Catalogが管理するストレージ資格情報を用いて外部ロケーション内のディレクトリに登録されるUnity Catalog管理のストレージボリュームです。外部ロケーションによって、既存のクラウドオブジェクトストレージのディレクトリにUnity Catalogのデータガバナンスを追加することができます。外部ボリュームのユースケースには以下のようなものがあります:

- マイグレーションすることなしに、データファイルにガバナンスを追加。
- Databricksによって取り込みあるいはアクセスされる必要がある、他のシステムで生成されたファイルの管理。
- 他のシステムによってクラウドオブジェクトストレージから直接アクセスされる必要がある、Databricksで生成されたデータの管理。

外部ロケーションは、Unity Catalogのストレージ資格情報で管理された外部ロケーション内の**ディレクトリである必要**があります。Unity Catalogは外部ボリュームのファイルのライフサイクルやレイアウトを管理しません。外部ボリュームを削除した際、Unity Catalogは背後のデータを削除しません。

# ボリュームのファイルへのアクセスに使われるパスは？

ボリュームにアクセスするためのパスは、Apache Spark、SQL、Python、他の言語やライブラリを使っていたとしても同じものとなります。これは、Databricksワークスペースに紐付けられていたオブジェクトストレージのファイルへのレガシーなアクセスパターンとは異なります。

ボリュームのファイルにアクセスするパスは以下の形式となります:

```
/Volumes/<catalog>/<schema>/<volume>/<path>/<file-name>
```

また、Apache Sparkを使用している際のオプションの`dbfs:/`スキーマにも対応していますので、以下のパスも動作します:

```
dbfs:/Volumes/<catalog>/<schema>/<volume>/<path>/<file-name>
```

パスの`/<catalog>/<schema>/<volume>`のシーケンスは、ファイルに関連づけられているUnity Catalogの3階層名前空間に対応しています。これらのパスの要素は読み込み専用であり、ユーザーによって直接書き込むことはできず、ファイルシステムオペレーションを用いてこれらのディレクトリを作成、削除することはできないことを意味します。これらは自動で管理され、対応するUCエンティティとの同期が保たれます。

# ボリュームの権限は？

ボリュームでは、テーブルと同じ基本権限モデルを使用しますが、テーブルの権限はテーブルの行のクエリーや操作に対するアクセスの付与にフォーカスしていますが、ボリュームの権限はファイルの操作にフォーカスしています。このため、ボリュームでは以下の権限を導入しています:

- [CREATE VOLUME](https://docs.databricks.com/data-governance/unity-catalog/manage-privileges/privileges.html#create-volume)
- [CREATE EXTERNAL VOLUME](https://docs.databricks.com/data-governance/unity-catalog/manage-privileges/privileges.html#create-external-volume)
- [READ VOLUME](https://docs.databricks.com/data-governance/unity-catalog/manage-privileges/privileges.html#read-volume)
- [WRITE VOLUME](https://docs.databricks.com/data-governance/unity-catalog/manage-privileges/privileges.html#write-volume)

[Unity Catalogにおける権限およびセキュリティ保護可能オブジェクト](https://qiita.com/taka_yayoi/items/57dfb4d1c5908c1f5d9e)をご覧ください。

# 誰がボリュームの権限を管理できる？

ボリュームの権限を管理したり、ボリュームを削除するにはオーナー権限が必要です。Unity Catalogのそれぞれのオブジェクトにはオーナーとして一つのプリンシパルのみを割り当てることができ、オーナーシップはカスケードしませんが(すなわち、カタログのオーナーは自動的にそのカタログ内のすべてのオブジェクトのオーナーにはなりません)、オーナーシップに関連づけられた権限は、オブジェクトに含まれるすべてのオブジェクトに適用されます。

これは、Unity Catalogのボリュームでは、以下のプリンシパルがボリューム権限を管理できることを意味します:

- 親のカタログのオーナー。
- 親のスキーマのオーナー。
- ボリュームのオーナー。

それぞれのオブジェクトには単一のオーナーが存在しますが、個々のユーザーではなくグループにお多くのオブジェクトのオーナーシップを割り当てることをお勧めします。すべてのオブジェクトの初期のオーナーシップは、オブジェクトを作成したユーザーに割り当てられます。[Manage Unity Catalog object ownership](https://docs.databricks.com/data-governance/unity-catalog/manage-privileges/ownership.html)をご覧ください。

# マネージドボリュームの作成

マネージドボリュームを作成するには以下の権限が必要です:

| リソース | 必要な権限 |
|:--|:--|
| スキーマ  |  `USE SCHEMA`, `CREATE VOLUME` |
| カタログ  | `USE CATALOG`  |

## SQL

マネージドボリュームを作成するには、以下の構文を使用します:

```sql:SQL
CREATE VOLUME <catalog>.<schema>.<volume-name>;
```

## データエクスプローラ

以下のステップを完了することで、データエクスプローラでマネージドボリュームを作成することができます。

1. Databricksワークスペースで![](https://docs.databricks.com/_images/data-icon.png)**Data**をクリックします。
1. ボリュームを追加したいスキーマをブラウズ、検索して選択します。
1. **Create Volume**ボタンをクリックします。(十分な権限が必要です。)
1. ボリューム名を入力します。
1. コメントを入力します(オプション)。
1. **Create**をクリックします。

# 外部ボリュームの作成

外部ボリュームを作成するには以下の権限が必要です:

| リソース | 必要な権限 |
|:--|:--|
| 外部ロケーション  | `CREATE EXTERNAL VOLUME`  |
| スキーマ  | `USE SCHEMA`, `CREATE VOLUME`  |
| カタログ  | `USE CATALOG`  |

## SQL

外部ボリュームを作成するには、以下の構文を用いて外部ロケーション内のパスを指定します:

```sql:SQL
CREATE EXTERNAL VOLUME <catalog>.<schema>.<external-volume-name>
LOCATION 's3://<external-location-bucket-path>/<directory>';
```

## データエクスプローラ

以下のステップを完了することで、データエクスプローラで外部ボリュームを作成することができます。

1. Databricksワークスペースで![](https://docs.databricks.com/_images/data-icon.png)**Data**をクリックします。
1. ボリュームを追加したいスキーマをブラウズ、検索して選択します。
1. **Create Volume**ボタンをクリックします。(十分な権限が必要です。)
1. ボリューム名を入力します。
1. ボリュームを作成する外部ロケーションを選択します。
1. ボリュームを作成したいサブディレクトリを反映するパスを編集します。
1. コメントを入力します(オプション)。
1. **Create**をクリックします。

# ボリュームの削除

オーナー権限を持つユーザーのみがボリュームを削除できます。[誰がボリュームの権限を管理できる？](#誰がボリュームの権限を管理できる)をご覧ください。

ボリュームを削除するには以下の構文を使用します:

```sql:SQL
DROP VOLUME IF EXISTS <volume-name>;
```

マネージドボリュームを削除すると、Databricksは30日以内に背後のデータを削除します。外部ボリュームを削除した際には、Unity Catalogからボリュームは削除されますが、背後のデータは外部ロケーションにそのまま残り続けます。

# ボリュームのファイルの読み込み

ボリュームのコンテンツを参照したり、ボリュームに格納されているファイルにアクセスするには以下の権限が必要です:

| リソース | 必要な権限 |
|:--|:--|
| ボリューム  | `READ`  |
| スキーマ  | `USE SCHEMA`  |
| カタログ  | `USE CATALOG`  |

パスを用いてボリュームのコンテンツを操作します。[ボリュームのファイルへのアクセスに使われるパスは？](#ボリュームのファイルへのアクセスに使われるパスは)をご覧ください。

# 外部ボリュームにおけるファイルの移動、作成、削除

ボリュームに格納されているファイルを移動、作成、削除するには以下の権限が必要です:

| リソース | 必要な権限 |
|:--|:--|
| ボリューム  | `READ`, `WRITE`  |
| スキーマ  | `USE SCHEMA`  |
| カタログ  | `USE CATALOG`  |

ファイルを操作するために、`%fs`、`%sh`マジックコマンドやDatabricksユーティリティの`fs`コマンド、`os.listdir()`のようなオープンソースのコマンドや[ボリュームへのファイルアップロードUI](https://docs.databricks.com/ingestion/add-data/upload-to-volume.html)を活用することができます。

# サンプルノートブック：Unity Catalogボリュームノートブック

以下のノートブックでは、Unity Catalogボリュームを作成し、操作を行うための基本的なSQL構文をデモストレーションしています。

https://docs.databricks.com/_extras/notebooks/source/unity-catalog-volumes.html

# ボリュームに予約されているパス

ボリュームによって、ボリュームにアクセスするために使用される以下の予約パスが導入されました:

- `dbfs:/Volumes`
- `/Volumes`

:::note
**注意**
また、先頭に`dbfs:/`がついているかどうかに関わらず、Apache Spark APIや`dbutils`におけるこれらのパスのtypoの可能性のある`/volumes`、`/Volume`、`/volume`も予約されています。`/dbfs/Volumes`も予約されていますが、ボリュームのアクセスにこれを使用することはできません。
:::

ボリュームはDatabricksランタイム13.2以降でのみサポートされています。Databricksランタイム13.1以前では、パス`/Volumes`に対するオペレーションが成功するかもしれませんが、期待するようにUnity Catalogのボリュームにデータを永続化するのではなく、計算クラスターにアタッチされた揮発性のストレージディスクにデータが書き込まれます。

:::note warn
**重要！**
DBFSルート上の予約パスにデータを保存している場合、別の場所にそのデータを一時的に移動するためにサポートチケットを作成することができます。
:::

# 制限

以下の制限があります:

- `/Volumes/<catalog-name>/<schema-name>`パターンを用いてUnity Catalogオブジェクトのリストを表示することはできません。ボリューム名を含む完全修飾パスを使う必要があります。
- ボリュームからファイルを削除するのにデータエクスプローラを使うことはできません。
- REST APIのDBFSエンドポイントではボリュームパスをサポートしていません。
- Databricksワークスペースのグローバル検索の結果からボリュームは除外されます。
- ボリュームからJARライブラリをインストールすることはできません。シングルユーザーアクセスモードのクラスターで、ボリュームからライブラリをインストールすることはできません。
- クラスターログ配信の宛先にボリュームを指定することはできません。
- ボリューム間のファイル移動で`%sh mv`はサポートされていません。`dbutils.fs.mv`や`%sh cp`を使ってください。
- データエクスプローラでは、ディレクトリあたり最大1000のファイルのみを表示します。
- Scalaでのボリュームサポートは、Apache Spark APIと`dbutils`に限定されます。UDFや他のScala IOコードはボリュームを用いてデータにアクセスすることはできません。
- ボリュームを用いてカスタムHadoopファイルシステムを作成することはできず、以下の処理はサポートされていないことを意味します:

    ```scala
    import org.apache.hadoop.fs.Path
    val path =  new Path("dbfs:/Volumes/main/default/test-volume/file.txt")
    val fs = path.getFileSystem(sc.hadoopConfiguration)
    fs.listStatus(path)
    ```

- AWS PrivateLinkが設定されたS3バケットで構築されたボリュームにファイルのアップロード、ダウンロードすることはできません。
- AWS GovCloudリージョンではボリュームは使えません。

### Databricksクイックスタートガイド

[Databricksクイックスタートガイド](https://www.amazon.co.jp/dp/B09V1YXFVQ/)


### Databricks無料トライアル

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