Azure Databricks Volumeによるファイルの読み書き

本投稿はAzure Databricks ボリューム(Volume)を作成し、ボリュームへのファイルの書き込みとファイルを読み込む方法を説明します。

※ なお、本記事は、Azure Databricksをある程度使い慣れている方向けに書いていますので、Azure Databricksの概要や用語の解説は割愛しています。

概要

ボリュームはUnity Catalog上でのスキーマ配下のオブジェクトであり、格納されたファイルに対して、読み書きなどのファイル操作が可能です。

格納できるファイルの種類は構造化データ、非構造化データ、半構造化データなど任意の形式での格納とアクセスが実行できます。

DBFSに対して、ボリュームを利用する利点

Databricksでは、ボリュームの他にファイルを取り扱う機能としてDBFSがありますが、いくつかの点でボリュームにはDBFSより優れた機能があります。

観点 Volume DBFS
アクセス制御の観点 ボリュームはUnity Catalogオブジェクトであるため、ボリューム単位でのアクセス制御が可能です。 DBFSはクラスタにマウントされたファイルシステムであるため、クラスタ上で作業する全ユーザーにファイルにアクセスできてしまうという欠点があります。
異なるワークスペース間でのアクセスの観点 ボリュームはUnity Catalogオブジェクトであるため、カタログ/スキーマへのUSE CATALOG権限、USE SCHEMA権限とともにボリュームへのREAD VOLUME権限やWRITE VOLUME権限が付与されたユーザー/グループであれば、アカウント内のどのワークスペースからでもアクセス可能です。 DBFSはクラスタにマウントしているため、特定のワークスペースのクラスタに依存してアクセスが制限される欠点があります。

なお、Databricksではいくつかの例外を除き、Unity Catalogが有効なワークスペースでは、DBFSよりもボリュームの使用が推奨されているようです。 learn.microsoft.com

ボリュームの種類

ボリュームの種類にはマネージドボリューム(Managed Volume)と外部ボリューム(External Volume)の2種類が存在します。

項目 マネージドボリューム 外部ボリューム
作成場所 ボリュームが格納されたスキーマの既定のクラウドストレージ上の保存場所内に作成 スキーマの規定のクラウドストレージ上の保存場所以外に作成
ストレージ資格情報 不要 必要
外部の場所 不要 必要
Unity Catalogから削除時の挙動 削除時にクラウドストレージ上のファイルも削除される。 削除時にクラウドストレージ上に実体ファイルは削除されず残存する。

検証構成

本投稿では上記構成でボリュームを作成します。

構成のストレージ資格情報(Storage Credential)と外部の場所(External Location)は外部ボリューム(External Volume)のために使用するものになります。

マネージドボリューム(Managed Volume)では構成図のストレージ資格情報と外部ボリュームは使用しません。

ストレージ資格情報及び外部の場所の所有者には、スキーマ所有者グループを設定することで、スキーマ所有者グループがAzure Databricks用のアクセス コネクタ(Access Connector for Azure Databricks)のマネージドIDを利用して、Azure ストレージアカウントのデータへアクセスします。ボリュームへの読み書きはREAD VOLUME権限またはWRITE VOLUME権限を付与されたユーザー権限が実施します。

※ マネージドボリュームもストレージ資格情報と外部の場所は利用しますが、マネージドボリュームの場合、スキーマと同様の外部の場所を利用するため、設定が不要となります。

Azureに作成するリソース

ストレージアカウント

外部ボリューム上に格納する実データは、クラウドストレージであるAzure ストレージアカウント上に配置されます。

Azure Databricks用のアクセス コネクタ

Azure Databricks用のアクセス コネクタはAzure Databricksアカウントへの接続可能なマネージド IDを提供するAzureリソースです。

リソース作成後に以下の追加設定を行うことで、Azure DatabricksからAzure ストレージアカウントへ接続することが可能となります。

  • Azure ストレージアカウントのストレージ BLOB データ共同作成者ロール(Storage Blob Data Contributor)をAzure Databricks用のアクセス コネクタに割り当て
  • Databricks Unity Catalogのオブジェクトであるストレージ資格情報(Storage Credential)に、Azure Databricks用のアクセス コネクタのリソースIDを格納

ボリューム以外のDatabricks Unity Catalogオブジェクト

ストレージ資格情報

Azure Databricks用のアクセス コネクタのリソースIDを格納するためのオブジェクトです。

外部の場所

ストレージの資格情報とクラウド オブジェクト ストレージ コンテナパスを紐づけるためのオブジェクトです。

ここで登録されたストレージ資格情報に格納されたリソースIDを利用して、同じく登録されたストレージアカウントコンテナパスへAzure Databricksからアクセスします。

カタログ

データ資産の整理に使用されるオブジェクト階層の最上位レイヤーです。

スキーマ

データ資産の整理に使用されるオブジェクト階層の二番目のレイヤーです。

検証内容

本投稿では、VOLUMEが使用できることと、以下の内容のアクセス制御が可能であることを検証します。

  • USER_GROUP01はREAD VOLUME及びWRITE VOLUME権限を付与し、読み書きが可能であることを確認します。
  • USER_GROUP02はREAD VOLUMEのみを付与し、読み取りのみ可能であることを確認します。
  • USER_GROUP03は権限を付与しないためボリューム操作ができないことを確認します。

検証のための前提条件

今回の構成に必要なDatabricksの構成の前提条件は下記の通りです。

  • Azure Databricksの価格レベルが「プレミアム」であること。
  • ワークスペースでUnity Catalogが有効になっていること。
  • Azure リソース グループの共同作成者または所有者であること。
  • ストレージ アカウントの所有者またはユーザー アクセス管理者 Azure RBAC ロールを持つユーザーであること。
  • アカウント管理者またはメタストア管理者権限を持つユーザーアカウントであること。

作成手順

外部ボリューム作成事前準備

Azure Databricks用アクセスコネクタ作成

本作業はAzureポータル UI上で実施します。

■Azure Databricks用アクセスコネクタの画面

「Azure Databricks 用アクセス コネクタの作成(Create access connector for azure databricks)」を押下します。

■Azure Databricks 用アクセス コネクタの作成 > 基本情報(Basics)

プロジェクト詳細に設定項目を記載し、「次へ(Next)」を押下します。

項目 設定/確認内容
サブスクリプション(Subscription) サブスクリプションを選択
リソースグループ(Resource group) リソースグループを選択
インスタンス(Instance details) > 名前(Name) リソース名を記載
インスタンス(Instance details) > リージョン(Region) リージョンを選択

■Azure Databricks 用アクセス コネクタの作成 > タグ(Tags)

設定する場合、内容を記載して「次へ(Next)」を押下します。

■Azure Databricks 用アクセス コネクタの作成 > Managed Identity

システム割り当てマネージドIDの状態 (System assigned managed identity)を「オン(ON)」にチェックし、「次へ(Next)」を押下します。

■Azure Databricks 用アクセス コネクタの作成 > 確認と作成(Review + create)

設定内容を確認後「作成(Create)」を押下するとリソースが作成されます。

Azure ストレージアカウント作成

本作業はAzureポータル UI上で実施します。

作業内容は以下記事をご参照下さい。 また「Hierarchical Namespace(階層型名前空間)」を有効にして、作成してください。 learn.microsoft.com

Azure ストレージアカウントのロール割り当て追加

本作業はAzureポータル UI上で実施します。

前の手順で作成したストレージアカウントのロール「ストレージ Blob データ 共同作成者(Storage Blob Data Contributor)」に作成済のAzure Databricks 用アクセス コネクタのマネージドIDを追加します。

■ロールの割り当ての追加(Add role assignment)

左メニュー「アクセス制御(IAM) (Access Control(IAM))」を押下後、「ロールの割り当て追加(Add role assignment)」を押下します。

■ロールの割り当て追加 > ロール(Role)

職務ロール(Job function roles)の一覧から、「ストレージ Blob データ 共同作成者(Storage Blob Data Contributor)」を選択して「次へ(Next)」を押下します。

■ロールの割り当ての追加 > メンバー(Members)

  • アクセスの割り当て先(Assign access to)で「マネージドID(Managed identity)」を選択します。
  • メンバー(Members)で「メンバーを選択する(Select members)」を押下後、「マネージドIDの選択(Select managed identities)」画面へ移行します。

■ロールの割り当ての追加 > メンバー(Members) > マネージドIDの選択(Select managed identities)

以下項目を選択し、「選択(Select)」を押下します。

項目 設定/確認内容
サブスクリプション(Subscription) サブスクリプションを選択
マネージドID(Managed identity) Azure Databricks 用のアクセス コネクタを選択
選択(Select) 作成したAzure Databricks 用のアクセス コネクタを選択

■ロールの割り当ての追加 > メンバー(Members)

設定内容を確認後「次へ(Next)」を押下します。

■ロールの割り当ての追加 > 条件(Conditions)

何も選択せず、「次へ(Next)」を押下します。

■ロールの割り当ての追加 > レビューと割り当て(Review + assign)

設定内容を確認後「レビューと割り当て(Review + assign)」を押下するとロールの割り当てが完了します。

Databricks ストレージ資格情報(Storage Credential)の作成

本作業はDatabricks UI上で実施します。

■カタログエクスプローラー > ストレージ資格情報(Storage Credential)

左メニューより「カタログ(Catalog)」を選択後、カタログエクスプローラー(Catalog Explore)よりストレージ資格情報(Storage Credential)を選択し、「資格情報を作成(Create credential)」を押下します。

■カタログエクスプローラー > ストレージ資格情報 > 新規のストレージ資格情報を作成(Create a new storage credential)

以下項目を記載し、「作成(Create)」を押下するとストレージ資格情報が作成されます。

項目 設定/確認内容
ストレージ資格情報名(Storage credential name) ストレージ資格情報(Storage credential )名を記載
アクセスコネクターID(Access connector ID) 本記事で作成したAzureリソースの「Azure Databricks 用のアクセス コネクタ」のリソースIDを記載

Databricks各オブジェクトの作成

本作業はDatabricks UI上で実施します。

■SQLエディタ(SQL Editor)を開く

左メニューより SQLエディタ(SQL Editor)を開きます。以降、クエリはここで開いたSQLエディタ上で記載し、実行します。

クエリは実行例となりますので、<>内のオブジェクト名は書き換えて実行してください。

■カタログの作成

CREATE CATALOG <Catalog>;

■スキーマの作成

CREATE SCHEMA <Catalog>.<Schema>;

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

CREATE VOLUME <Catalog>.<Schema>.<Managed_Volume>;

■外部の場所の作成

CREATE EXTERNAL <External_Location>
    URL 'abfss://<Container>@<Storage_Account>.dfs.core.windows.net/<External_Location_Path>'
    WITH (CREDENTIAL <Storage_Credential>)
;

■外部ボリュームの作成

CREATE EXTERNAL VOLUME <Catalog>.<Schema>.<External_Volume>
    LOCATION 'abfss://<Container>@<Storage_Account>.dfs.core.windows.net/<External_Volume_Path>'
;

■各オブジェクトの所有者変更と権限付与

本作業はDatabricks クエリエディタ上で実施します。

Databricksではオブジェクト作成時の所有者はログインユーザーになっていますので、それぞれ適切な所有者へ変更します。

ALTER STORAGE CREDENTIAL <Storage_Credential>                 OWNER TO <Schema_Owner_Group>;
ALTER EXTERNAL LOCATION  <External_Location>                  OWNER TO <Schema_Owner_Group>;
ALTER CATALOG            <Catalog>                            OWNER TO <Catalog_Owner_Group>;
ALTER SCHEMA             <Catalog>.<Schema>                   OWNER TO <Schema_Owner_Group>;
ALTER VOLUME             <Catalog>.<Schema>.<Managed_Volume>  OWNER TO <Schema_Owner_Group>;
ALTER VOLUME             <Catalog>.<Schema>.<External_Volume> OWNER TO <Schema_Owner_Group>;

カタログのUSE CATALOG権限をスキーマ所有者グループと各ユーザーグループへ付与します。

GRANT USE CATALOG  ON CATALOG <Catalog> TO <Schema_Owner_Group>;
GRANT USE CATALOG  ON CATALOG <Catalog> TO <User_Group01>;
GRANT USE CATALOG  ON CATALOG <Catalog> TO <User_Group02>;
GRANT USE CATALOG  ON CATALOG <Catalog> TO <User_Group03>;

スキーマ権限を各ユーザーグループへ付与します。

  • スキーマのUSE SCHEMA権限を各グループへ付与します。
  • スキーマ配下のボリュームに対するREAD VOLUME権限をユーザーグループの01と02へ付与します。
  • スキーマ配下のボリュームに対するWRITE VOLUME権限をユーザーグループの01へ付与します。
GRANT USE SCHEMA   ON SCHEMA <Catalog>.<Schema> TO <User_Group01>;
GRANT USE SCHEMA   ON SCHEMA <Catalog>.<Schema> TO <User_Group02>;
GRANT USE SCHEMA   ON SCHEMA <Catalog>.<Schema> TO <User_Group03>;
GRANT READ VOLUME  ON SCHEMA <Catalog>.<Schema> TO <User_Group01>;
GRANT READ VOLUME  ON SCHEMA <Catalog>.<Schema> TO <User_Group02>;
GRANT WRITE VOLUME ON SCHEMA <Catalog>.<Schema> TO <User_Group01>;

検証

検証時に使用するグループにのみ自アカウントを追加して検証していきます。

ボリュームへのファイルの配置

配置するサンプルデータ: databricks-datasets配下のiot-stream/data-device/をローカルPCにダウンロードして使用します。

参考URL:

qiita.com

アップロード方法

アップロード方法は、マネージドボリュームでも外部ボリュームでも方式に違いはありません。

■カタログエクスプローラでの対象ボリュームの参照

左メニューより「カタログ(Catalog)」を選択後、カタログエクスプローラー(Catalog Explore)より対象カタログ、スキーマ、ボリュームを選び、「このボリュームにアップロード(Upload to this volume」を押下します。

■ファイルの書き込み(アップロード)

パス(Path)とローカルPCにダウンロードしたファイルを指定して「アップロード(Upload)」を押下します。

USER_GROUP01による実行

Volume上のアップロード先パスでファイルがアップロードされていることが確認できます。

USER_GROUP02, 03による実行

対象グループにはWRITE VOLUME権限が付与されていないため、「このボリュームにアップロード(Upload to this volume」が無効化されていて押下できなくなっています。

ボリュームのファイル読み取り

USER_GROUP01, 02による実行
SELECT
      id
    , GET_JSON_OBJECT(value, "$.user_id")        AS userId
    , GET_JSON_OBJECT(value, "$.calories_burnt") AS caloriesBurnt
    , GET_JSON_OBJECT(value, "$.num_steps")      AS numSteps
    , GET_JSON_OBJECT(value, "$.miles_walked")   AS milesWalked 
    , GET_JSON_OBJECT(value, "$.time_stamp")     AS timestamp
    , GET_JSON_OBJECT(value, "$.device_id")      AS deviceId
    , SPLIT(_metadata.file_path, '/')[8]         AS fileName
FROM json.`/Volumes/<Catalog>/<Schema>/<Volume>/<Path>`
;

対象グループにはREAD VOLUME権限が付与されているため、処理結果が返ってきます。

USER_GROUP03による実行
SELECT
      id
    , GET_JSON_OBJECT(value, "$.user_id")        AS userId
    , GET_JSON_OBJECT(value, "$.calories_burnt") AS caloriesBurnt
    , GET_JSON_OBJECT(value, "$.num_steps")      AS numSteps
    , GET_JSON_OBJECT(value, "$.miles_walked")   AS milesWalked 
    , GET_JSON_OBJECT(value, "$.time_stamp")     AS timestamp
    , GET_JSON_OBJECT(value, "$.device_id")      AS deviceId
    , SPLIT(_metadata.file_path, '/')[8]         AS fileName
FROM json.`/Volumes/<Catalog>/<Schema>/<Volume>/<Path>`
;

対象グループにはREAD VOLUME権限が付与されていないため、処理が失敗します。

検証結果で、WRITE VOLUME権限とREAD VOLUME権限は正しく機能していることが確認できました。

まとめ

本記事ではAzure DatabricksのVolumeによるファイルの読み書き方法の説明と検証を行いました。

今後もAzure Databricksに関する記事を投稿する予定ですので、是非ご一読下さい。

執筆担当者プロフィール
佐藤 史彦

佐藤 史彦(日本ビジネスシステムズ株式会社)

Azure、AWS、Snowflake、Databricksなどを扱っています。

担当記事一覧