Databricks Unity Catalogのベストプラクティス

[Unity Catalog best practices](https://docs.databricks.com/data-governance/unity-catalog/best-practices.html) [2022/11/23時点]の翻訳です。

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

本書では、皆様のデータガバナンス要件を満たすために、どのようにDatabricks Unity CatalogとDelta Sharingを導入するのがベストなのかに関して主張できる観点を提供します。

# Unity Catalogメタストアの設定

Unity Catalogは、DatabricksレイクハウスにおけるデータとAIに対するきめ細かいガバナンスソリューションです。データアクセスを集中的に管理、監査できる場所を提供することで、データに対するセキュリティ、ガバナンスをシンプルにする助けとなります。以下の図では、Unity Catalogにおける主要なセキュリティ保護可能オブジェクトを示しています。
![](https://docs.databricks.com/_images/object-model.png)

メタストアはUnity Catalogにおけるトップレベルのコンテナです。データ資産(テーブルやビュー)とそれらに対するアクセスを管理する権限を格納します。Databricksのアカウント管理者はメタストアを作成し、どのワークロードがどのメタストアを使用するのかをコントロールするためにDatabricksワークスペースに割り当てることができます。オペレーションを行うそれぞれのリージョンに一つのメタストアを作成し、当該リージョンのすべてのワークスペースにリンクさせます。このため、Databricksが複数のリージョンで稼働している場合、複数のメタストアを持つことになります。メタストア間でデータを共有するには、[Delta Sharing](#delta-sharing)を使用します。

それぞれのメタストアには、マネージドテーブルで使用されるルートストレージロケーションが設定されます。このストレージロケーションにいかなるユーザーも直接のアクセス権を持たない様にする必要があります。ストレージロケーションへのアクセスを許可すると、ユーザーはUnity Catalogメタストアによるアクセスコントロールを迂回し、監査可能性を阻害することになります。これらの理由から、現在DBFSのルートファイルシステムに使用しているバケットや、Unity Catalogメタストアのルートストレージロケーションとして使用していたDBFSルートファイルシステムのバケットを再利用すべきではありません。

[Create a Unity Catalog metastore](https://docs.databricks.com/data-governance/unity-catalog/create-metastore.html)をご覧ください。

## 外部ロケーションとストレージ認証情報

外部ロケーションとストレージ認証情報を用いることで、Unity Catalogがユーザーに代わってクラウドテナントのデータを読み書きできる様になります。

*ストレージ認証情報*は、クラウドストレージに対するアクセスを適用する長期間保持されるクラウドの認証情報をカプセル化します。例えば、AWSではS3バケットにアクセスするためにIAMロールを設定することができます。

*外部ロケーション*は、クラウドストレージパスへのアクセスを許可するための、クラウドストレージのパスとストレージ認証情報を組み合わせたオブジェクトです。

ストレージ認証情報を直接使うのではなく、外部ロケーションを用いることをお勧めします。外部ロケーションとして使用されるバケットに直接アクセスできるユーザーの数を限定すべきです。これは、ユーザーがUnity Catalogメタストアのアクセスコントロールを迂回し、監査可能性を損なうことを防ぐためのものです。このため、外部ロケーションとして使用されるDBFSをストレージアカウントにマウントすべきではありません。

[データエクスプローラー](https://docs.databricks.com/data/index.html)を用いて、クラウドストレージロケーションへのマウントをUnity Catalogの外部ロケーションに移行することをお勧めします。

[Unity Catalogにおける外部ロケーションとストレージ認証情報の管理](https://qiita.com/taka_yayoi/items/18fee92365eee58e0b94)をご覧ください。

# データの整理

皆様の組織の情報アーキテクチャにおける区域を提供するためにカタログを使用することをお勧めします。多くの場合、これはカタログがソフトウェア開発環境のスコープ、チーム、ビジネスユニットに対応することを意味します。
![](https://docs.databricks.com/_images/uc-catalogs.png)

スキーマ(データベースよも呼ばれます)は、Unity Catalogの[3レベル名前空間](https://docs.databricks.com/data-governance/unity-catalog/queries.html#three-level-namespace-notation)の2番目のレイヤーであり、テーブルやビューを整理します。テーブルはマネージドあるいは外部テーブルとなります。

Unity Catalogにおいてテーブルを作成する際、マネージドテーブルがデフォルトとなります。これらのテーブルはメタストアを作成した際に指定したUnity Catalogのルートストレージロケーションに格納されます。Unity Catalogの機能サポートを確実にするために、可能な限りマネージドテーブルを使用することをお勧めします。すべてのマネージドテーブルはDelta Lakeを使用します。

外部テーブルは、マネージドのストレージロケーションの外のストレージロケーションにデータが格納されるテーブルです。これらはUnity Catalogによって完全には管理されません。外部テーブルでは、Delta Lakeや、Parquet、JSON、CSVを含む数多くのデータフォーマットをサポートしています。生のデータに対する直接アクセスを提供する際、外部テーブルは好適なオプションと言えます。

テーブルの作成に関しては、[Create tables](https://docs.databricks.com/data-governance/unity-catalog/create-tables.html)をご覧ください。

## 外部ロケーションと外部テーブルの管理

以下の図では、単一のクラウドストレージバケットにおけるファイルシステムの階層構造を示しています。
[Create tables](https://docs.databricks.com/data-governance/unity-catalog/create-tables.html)

4つの外部ロケーションが作成され、それらすべてによって使用される1つのストレージ認証情報があります。ユーザーやグループには、Unity Catalogメタストア内の別々のストレージロケーションに対してアクセスを許可することができます。これによって、特定のグループに対してクラウドストレージバケットの別の部分へのアクセスを許可することができます。

Unity Catalogメタストアのストレージロケーションを用いて外部テーブルをs買う制することができます。これらの外部テーブルは独立にセキュリティ保護することができます。1つのスキーマ内の1つのストレージロケーションから外部テーブルを作成することをお勧めします。

一貫性に関する問題のリスクから、1つ以上のメタストアの外部テーブルとして共通のテーブルを登録することは強くお勧めしません。例えば、1つのメタストアにおけるスキーマへの変更は、2番目のメタストアに登録されません。メタストア間でデータを共有するには、[Delta Sharing](#delta-sharing)を使用してください。

# アクセスコントロールの設定

Unity Catalogにおける個々のセキュリティ保護可能オブジェクトにはオーナーが存在します。オブジェクトを作成したプリンシパルが最初のオーナーとなります。オブジェクトのオーナーは、テーブルのSELECTやMODIFY、他のプリンシパルにセキュリティ保護可能オブジェクトの権限を付与する権利など、オブジェクトに対するすべての権限を有します。このため、オブジェクトに対する権限付与に責任を持つ**グループ**に、すべてのオブジェクトに対するオーナーシップを設定することがベストプラクティスとなります。オーナーとメタストア管理者の両方が、セキュリティ保護可能オブジェクトのオーナーをグループに移譲することができます。さらに、(テーブルやビューなど)オブジェクトがカタログに含まれている場合、カタログとスキーマのオーナーがオブジェクトのオーナーシップを変更することができます。

Unity Catalogにおけるセキュリティ保護可能オブジェクトは階層的であり、権限は下方に継承されます。これは、カタログやスキーマに対して付与した権限が、カタログやスキーマに存在する、あるいは今後作成されるオブジェクトすべてに自動で権限が付与されることを意味します。詳細に関しては、[Inheritance model](https://docs.databricks.com/data-governance/unity-catalog/manage-privileges/privileges.html#inheritance)をご覧ください。

テーブルやビューからデータを読み込むには、ユーザーは以下の権限を有している必要があります:

- テーブルやビューに対する`SELECT`
- テーブルを保持するスキーマに対する`USE SCHEMA`
- スキーマを保持するカタログに対する`USE CATALOG`

`USE CATALOG`によって、許可されたユーザーが子供のオブジェクトにアクセするためにカタログを移動でき、`USE SCHEMA`によって、許可されたユーザーが子供のオブジェクトにアクセスするためにスキーマを移動できます。例えば、テーブルからデータを取得するには、ユーザーはテーブルに対する`SELECT`権限を有している必要があり、親のカタログに対する`USE CATALOG`権限と、親のスキーマに対する`USE SCHEMA`権限が必要となります。このため、特定のグループに対してご自身のデータ名前空間のセクションへのアクセスを制限するために、この権限を活用することができます。一般的なシナリオは、チームごとにスキーマをセットアップし、当該チームのみがそのスキーマに対する`USE SCHEMA`と`CREATE`権限を持つというものです。これは、チームメンバーによって作成されたすべてのテーブルはチーム内でのみ共有されるということを意味します。

以下のSQL文法を用いてテーブルへのアクセスをセキュアにすることができます。

```sql:SQL
GRANT USE CATALOG ON CATALOG < catalog_name > TO < group_name >;
GRANT USE SCHEMA ON SCHEMA < catalog_name >.< schema_name >
TO < group_name >;
GRANT
SELECT
  ON < catalog_name >.< schema_name >.< table_name >;
TO < group_name >;
```

以下のSQL構文にあるように、2つ目のスキーマのダイナミックビューを用いてカラムへのアクセスをセキュアにすることができます。

```sql:SQL
CREATE VIEW < catalog_name >.< schema_name >.< view_name > as
SELECT
  id,
  CASE WHEN is_member(< group_name >) THEN email ELSE 'REDACTED' END AS email,
  country,
  product,
  total
FROM
  < catalog_name >.< schema_name >.< table_name >;
GRANT USE CATALOG ON CATALOG < catalog_name > TO < group_name >;
GRANT USE SCHEMA ON SCHEMA < catalog_name >.< schema_name >.< view_name >;
TO < group_name >;
GRANT
SELECT
  ON < catalog_name >.< schema_name >.< view_name >;
TO < group_name >;
```

以下のSQL構文を用いて、2つ目のスキーマのダイナミックビューを用いて行へのアクセスをセキュアにすることができます。

```sql:SQL
CREATE VIEW < catalog_name >.< schema_name >.< view_name > as
SELECT
  *
FROM
  < catalog_name >.< schema_name >.< table_name >
WHERE
  CASE WHEN is_member(managers) THEN TRUE ELSE total <= 1000000 END;
GRANT USE CATALOG ON CATALOG < catalog_name > TO < group_name >;
GRANT USE SCHEMA ON SCHEMA < catalog_name >.< schema_name >.< table_name >;
TO < group_name >;
GRANT
SELECT
  ON < catalog_name >.< schema_name >.< table_name >;
TO < group_name >;
```

[Manage privileges in Unity Catalog](https://docs.databricks.com/data-governance/unity-catalog/manage-privileges/index.html)をご覧ください。

# クラスター設定の管理

一連のルールに基づいてクラスターを設定する能力を制限するために、クラスターポリシーを用いることをお勧めします。クラスターポリシーによって、Unity Catalogが有効化されたクラスターのみを作成できる様に制限をかけることができます。クラスターポリシーを用いることで選択肢を削減し、ユーザーのクラスター作成プロセスをシンプルにし、シームレスにデータにアクセスできる様になります。また、クラスターポリシーで、クラスタあたりの最大コストを制限することでコストをコントロールすることができます。

アクセスコントロールの一貫性を保証し、強力なアイソレーション保証を強制するために、Unity Catalogは計算資源に対するセキュリティ要件を課します。このため、Unity Catalogではクラスターのアクセスモードというコンセプトを導入しています。Unity Catalogはデフォルトで保護されています。クラスターに適切なアクセスモードが設定されていない場合、クラスターはUnity Catalogのデータにアクセスすることができません。[Unity Catalogにおけるクラスターアクセスモード](https://qiita.com/taka_yayoi/items/15aede468bdca58ec6a3#unity-catalog%E3%81%AB%E3%81%8A%E3%81%91%E3%82%8B%E3%82%AF%E3%83%A9%E3%82%B9%E3%82%BF%E3%83%BC%E3%82%A2%E3%82%AF%E3%82%BB%E3%82%B9%E3%83%A2%E3%83%BC%E3%83%89)をご覧ください。

クラスターを共有する際にはユーザー分離アクセスモードを使用し、自動化ジョブや機械学習ワークロードにはシングルユーザーアクセスモードを使うことをお勧めします。

以下のJSONでは、ユーザー分離セキュリティモードの共有クラスターに対するポリシー定義を示しています。

```json:JSON
{
"spark_version": {
    "type": "regex",
    "pattern": "1[0-1]\\.[0-9]*\\.x-scala.*",
    "defaultValue": "10.4.x-scala2.12"
},
"access_mode": {
    "type": "fixed",
    "value": "USER_ISOLATION",
    "hidden": true
}
}
```

以下のJSONでは、シングルユーザーセキュリティモードの自動化ジョブクラスターに対するポリシー定義を示しています。

```json:JSON
{
"spark_version": {
    "type": "regex",
    "pattern": "1[0-1]\\.[0-9].*",
    "defaultValue": "10.4.x-scala2.12"
},
"access_mode": {
    "type": "fixed",
    "value": "SINGLE_USER",
    "hidden": true
},
"single_user_name": {
    "type": "regex",
    "pattern": ".*",
    "hidden": true
}
}
```

# 監査アクセス

完全なデータガバナンスソリューションには、アラート、モニタリング能力を提供するデータアクセスの監査が必要となります。Unity Catalogはメタストアに対するアクションの監査ログを取得し、Databricks監査ログの一部としてデリバリーされます。

[監査ログの設定](https://docs.databricks.com/administration-guide/account-settings/audit-logs.html)を確認してください。これには、あなたが指定するS3バケットにDatabricksが監査ログをデリバリーできる様にするための適切なアクセスポリシーの設定が含まれています。通常、監査ログは15分以内に記録されます。アカウント内のすべてのワークスペースで同じ監査ログ設定を使用する様にしてください。

お使いのDatabricksレイクハウスプラットフォームに関連する重要なイベントに対する完全なる可視性をどの様に得るのかに関しては、[監査ログによるDatabricksレイクハウスプラットフォームのモニタリング](https://qiita.com/taka_yayoi/items/2c019d8fc735e55af81b)をご覧ください。

# Delta Sharing

[Delta Sharing](https://qiita.com/taka_yayoi/items/08f0bd54995346e85674)は、使用している計算プラットフォームに関係なく企業内の別部門、あるいは別組織とセキュアにデータを共有するためにDatabricksによって開発されたオープンプロトコルです。メタストアでDelta Sharingが有効化されると、Unity CatalogはDelta Sharingサーバーを稼働させます。

メタストア間でデータを共有するには、[Databricks\-to\-Databricks Delta Sharing](https://docs.databricks.com/data-sharing/index.html#d-to-d)を活用することができます。これによって、別のリージョンのメタストアからテーブルを登録することができます。これらのテーブルは利用するメタストアで読み取り専用オブジェクトとして表示されます。これらのテーブルは他のUnity Catalogのオブジェクトと同じようにアクセス権を設定することができます。

メタストア間でDatabricks-to-Databricks Delta Sharingを用いる際、アクセスコントロールは一つのメタストアに限定されることに注意してください。テーブルの様なセキュリティ保護可能オブジェクトにアクセス権が設定されており、そのリソースがイントラアカウントのメタストアに共有された場合、ソースからの権限が対象の共有には適用されません。対象の共有においては自身で権限を付与する必要があります。

# より詳細を学ぶ

- [Unity Catalogを使い始める](https://qiita.com/taka_yayoi/items/3f2df6ddea81521ee786)
- [Share data securely using Delta Sharing](https://docs.databricks.com/data-sharing/index.html)
- [テーブルとビューをUnity Catalogにアップグレードする](https://qiita.com/taka_yayoi/items/5e896b50b915b9de8fb3)

### Databricks 無料トライアル

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