Azure Databricks から OneLake 上のデータにアクセスする方法 2024/12 版

## はじめに

[Azure Databricks の Unity Catalog ミラーリング](https://learn.microsoft.com/ja-jp/fabric/database/mirrored-database/azure-databricks) を通して、Databricks の管理するデータについて Fabric で利用できるようになりましたが、Fabric レイクハウスなどの OneLake に格納されたデータに Azure Databricks からアクセスする方法を検討・検証してみます。

## 方式案と結果まとめ

| 方式 | ストレージアクセスとしての推奨度合 | 結果 | 備考 |
|:-:|:-:|:-:|:-:|
|資格情報パススルークラスターを使用したアクセス   | 非推奨の記載あり  | △| SQL ウェアハウスでは不可  |
|Spark 構成設定による Azure Storage アクセス    | レガシーパターン | 〇  |   |
|外部ロケーション   | UnityCatalogでは推奨  | × |   |
|ストレージ資格情報を使用して直接アクセス   | 外部ロケーションの利用が推奨  | ×  |   |
|レイクハウスフェデレーション   |記載なし| ×  | 今後使えそうな表示あり  |
|（番外）ハブストレージを介しての相互アクセス|双方サポートされた方式|〇|

## 1. 資格情報パススルークラスターを使用したアクセス

[OneLake と Azure Databricks の統合](https://learn.microsoft.com/ja-jp/fabric/onelake/onelake-azure-databricks) にて記載のある方法です。

ただし、Azure Databricks 的には非推奨のパターンとなります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281819/014144bf-683a-5cc7-80cd-7a71713c242e.png)
引用：https://learn.microsoft.com/ja-jp/azure/databricks/archive/credential-passthrough/adls-passthrough

### 準備

[Microsoft Fabric でサンプル ウェアハウスを作成する](https://learn.microsoft.com/ja-jp/fabric/data-warehouse/create-warehouse-sample) を参考にウェアハウスを作成しておきます。

### 検証

1. 資格情報パススルーを有効にしたクラスターを作成します。
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281819/96318201-bcd5-7daa-bd9f-202208d0ac7a.png)
1. ウェアハウスの対象テーブルの abfss パスを記録します。
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281819/3bb43e11-9eb5-f706-439b-670faa05aff2.png)
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281819/96900332-d64a-f4fb-8109-2bacd9c25967.png)
1. 対象のパスからロードしてみます。
    ```python:pyspark
    
    onelake_path = "確認したabfssパス"
    trip_df = spark.read.format("delta").load(onelake_path)
    display(trip_df)
    
    ```
    成功
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281819/c7443335-de44-7cd5-845c-c18d36c502ae.png)
1. 外部テーブルとして作成してみましょう。
    Unity Catalog ではこのクラスターは使えないので、エラーとなります。
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281819/6e28ec57-d0b7-f151-93ba-fbed5b6765c2.png)
1. Hive Metastore 上だと作成が可能です。
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281819/6dd89e61-a2ca-084d-7546-c950dcf6d283.png)
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281819/a83a0130-f6b8-508e-0610-049bab0c0c8b.png)
1. ただし、 SQL ウェアハウスはパススルーのような構成が不可なので、カタログエクスプローラーや SQL エディターではクエリができないことがわかります。
    カタログエクスプローラー
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281819/180fdf52-28c7-c78b-9bc8-a23a625523e6.png)
    SQL エディタ
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281819/43a08191-a1b4-72c8-6f97-9abd6b5b209b.png)

以上のように、Docs に記載の内容にもかかわらず、制約が厳しい利用方法だということがわかりました。

## 2. Spark 構成設定による Azure Storage アクセス 

[サービスプリンシパルを利用してアクセスする](https://qiita.com/ryoma-nagata/items/66c48dd2a86956c0d00d#%E3%82%B5%E3%83%BC%E3%83%93%E3%82%B9%E3%83%97%E3%83%AA%E3%83%B3%E3%82%B7%E3%83%91%E3%83%AB%E3%82%92%E5%88%A9%E7%94%A8%E3%81%97%E3%81%A6%E3%82%A2%E3%82%AF%E3%82%BB%E3%82%B9%E3%81%99%E3%82%8B) でまとめた方式です。

OneLake は Azure Data Lake Storage 互換のエンドポイントをもつため実現が可能な方式です。（参照：[OneLake の実体について](https://qiita.com/ryoma-nagata/items/3106ff09079b71bf3af3)）

ただし、mslearn docs では、レガシーパターンとして、Unity Catalog の機能を使用してアクセスすることが推奨されています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281819/00cc6249-4619-f1d6-2a39-d1897a828ee6.png)
引用：https://learn.microsoft.com/en-us/azure/databricks/connect/storage/azure-storage

### 準備

- [Microsoft Fabric でサンプル ウェアハウスを作成する](https://learn.microsoft.com/ja-jp/fabric/data-warehouse/create-warehouse-sample) を参考にウェアハウスを作成しておきます。
- [サービスプリンシパルを作成](https://learn.microsoft.com/en-us/azure/databricks/connect/storage/aad-storage-service-principal)し、Databricks 上 で [シークレットを登録](https://learn.microsoft.com/ja-jp/azure/databricks/security/secrets/#manage-secrets)しておきます。
- レイクハウスも作成しておきます。

### 検証

1. 作成したサービスプリンシパルを Fabric ワークスペースの共同作成者に設定します。
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281819/8ff314c0-5c9e-7e00-0ee4-182b4d19589d.png)

1. 通常のクラスターでノートブックを起動し、spark構成設定を以下のように設定します。Azure Storage の場合に使用する dfs.windows.net ではなく、onelake.dfs.fabric.microsoft.comに対しての認証設定を構成している点に注目
    
    ```python:pyspark
        
        service_credential = dbutils.secrets.get(scope="シークレットスコープ名",key="シークレット名")
        spark.conf.set("fs.azure.account.auth.type.onelake.dfs.fabric.microsoft.com", "OAuth")
        spark.conf.set("fs.azure.account.oauth.provider.type.onelake.dfs.fabric.microsoft.com", "org.apache.hadoop.fs.azurebfs.oauth2.ClientCredsTokenProvider")
        spark.conf.set("fs.azure.account.oauth2.client.id.onelake.dfs.fabric.microsoft.com", "サービスプリンシパルクライアントID")
        spark.conf.set("fs.azure.account.oauth2.client.secret.onelake.dfs.fabric.microsoft.com", service_credential)
        spark.conf.set("fs.azure.account.oauth2.client.endpoint.onelake.dfs.fabric.microsoft.com", "https://login.microsoftonline.com/テナントID/oauth2/token")
    
    
    ```
2.  ロードします。
   
    ```python:pyspark
    
    onelake_path = "確認したabfssパス"
    trip_df = spark.read.format("delta").load(onelake_path)
    display(trip_df)
    
    ```
    
    成功
    
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281819/7754ca0f-da0e-ddad-a9da-0b1fe028cfb9.png)

3. 試しに書き込みもしてみます。
    ウェアハウスでは失敗します。spark での書き込みが許可されないためですね
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281819/ce9b590c-3bf3-7bbe-cf34-26a400484de8.png)
    レイクハウスだと成功
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281819/e1873267-961f-d837-68bf-6ecb98af97d9.png)
    Fabric 側ですぐに利用できます。
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281819/5e116a6f-d3ae-1907-6d19-f79f0bea42b3.png)

4. 外部テーブルを作成してみます。
    Unity Catalog では外部ロケーションに設定されていないストレージで外部テーブルを作ろうとするとエラーとなります。
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281819/9c1ceafe-9035-2916-1819-9a476510ea2c.png)
    Hive Metastore 側だと成功します。
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281819/7817a00a-191c-c7fc-4b28-72387e7611bd.png)

4. SQL ウェアハウスでアクセスする場合には、[データアクセスの構成](https://learn.microsoft.com/ja-jp/azure/databricks/admin/sql/data-access-configuration#configure-data-access-properties-for-sql-warehouses)を行います。
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281819/9fc47bb4-836a-1971-9e12-5df2f3fc5c1c.png)
5. SQL ウェアハウスで構成設定ができていると、カタログエクスプローラーからもテーブルが確認できるようになります。
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281819/e87d9ed3-5d7d-d069-fe9b-21587c6e1f5e.png)

5. もちろんクエリ可能
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281819/5f5f9d57-a8cd-95e8-fbed-6794b0154214.png)


以上のように、Spark 構成設定によりOneLake へのサービスプリンシパルアクセスができました。
Unity catalog で管理できない点だけが難点ですが、現時点では最も機能の制限が少なく使いやすい方式だと思います。

## 3. 外部ロケーション 

[クラウド ストレージを Azure Databricks に接続するための外部の場所を作成する](https://learn.microsoft.com/ja-jp/azure/databricks/connect/unity-catalog/cloud-storage/external-locations) を OneLake に対して構成してみます

### 準備

- [Microsoft Fabric でサンプル ウェアハウスを作成する](https://learn.microsoft.com/ja-jp/fabric/data-warehouse/create-warehouse-sample) を参考にウェアハウスを作成しておきます。
- Databricks アクセスコネクタなどの、Unity Catalog メタストアを構成する際に使用しているIDをFabric ワークスペースの共同作成者に設定しておきます。
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281819/42e57ee2-0cd4-e3bb-f017-2dc1bdff4b5c.png)
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281819/c6e32325-8e0b-8431-af1e-bd065a961333.png)


### 検証

1. カタログエクスプローラーから外部ロケーションの設定にすすみます。
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281819/f20b83dc-e8fb-5666-275f-f9d13a7b5ac7.png)
1. 作成をクリック
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281819/8e639759-af3e-5bf1-b5c3-8742661b68b3.png)
1. これまで使用した abfss パスを入力して作成します。結果はエラー。 Fabric OneLake は不可のようです。
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281819/6bcbba9d-6c03-b643-0279-4cf26ef35016.png)

この方式で作成できることを期待していましたが、現時点ではサポートされていないので、今後よりスマートな方法が提供されることが期待されます。

## 4. ストレージ資格情報を使用して直接アクセス

### 準備

- レイクハウスを作成しておきます。
- Databricks アクセスコネクタなどの、Unity Catalog メタストアを構成する際に使用しているIDをFabric ワークスペースの共同作成者に設定しておきます。
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281819/42e57ee2-0cd4-e3bb-f017-2dc1bdff4b5c.png)
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281819/c6e32325-8e0b-8431-af1e-bd065a961333.png)

### 検証

1. コードを実行して直接アクセスしてみます。エラー内容的にも Fabric はサポートされていないようです。
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281819/f6fb5edd-cd70-6f66-f754-f7672dfcced4.png)
2. https 形式でも不可
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281819/dedc046c-d243-8b0a-b9b9-14a4a8a105c2.png)

外部ロケーションでブロックされた時点でうすうすわかってはいましたが、やはり不可でした。

## 5. レイクハウスフェデレーション

[レイクハウスフェデレーション](https://learn.microsoft.com/ja-jp/azure/databricks/query-federation/) で Fabric に接続することはできるのでしょうか

### 検証

1. フェデレーション先の接続を作成するコードを不完全ながら実行してみると以下のようにエラーとなりました。
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281819/a99c1e3e-9bb7-c150-2e2b-2515097e9df2.png)
1. メッセージから推察し、TYPE を Fabric にしてみると、まだ有効化されていない旨のメッセージ。
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281819/1c0d3824-d653-4611-91a6-f883897cf45a.png)

結果は失敗ですが、今後のサポートが期待される結果となりました。

## 6. (番外) ハブストレージを介しての相互アクセス

Fabric  -> ショートカット
Databricks -> 外部ロケーション

という形で相互にアクセスするストレージを介して接続してみます。

### 準備

- Azure Data Lake Storage を作成しておきます。
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281819/323fd33d-3092-9fe2-3fed-e1434d31fe71.png)

### 検証

1. Fabric 側で スキーマが有効なレイクハウスを作成
    スキーマが有効なレイクハウスは[現時点での制限](https://learn.microsoft.com/ja-jp/fabric/data-engineering/lakehouse-schemas#public-preview-limitations)が多いのですが、スキーマレベルでショートカットしておけば配下のテーブルを自動的にレイクハウスで認識できるはずという狙いです。
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281819/94154dcb-35d3-2e36-1e71-1bafdd56ae3e.png)

1. ショートカットを作成
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281819/0228f9c5-cf22-9fa9-45cb-bbd58a5fc81f.png)
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281819/da9fc9ec-6fc0-09f6-7d38-b72840e52a05.png)
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281819/4b799c10-ad0c-1418-e789-333882ad9998.png)
2. Unity Catalog の資格情報に権限付与
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281819/0c21e440-e5bd-c23d-5cec-153a173a2e5a.png)
3. 外部ロケーションを作成
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281819/8e2acdf9-9546-2f99-9cac-b51bbd27f2be.png)
4. 外部ロケーションの利用権限を付与しておきます。
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281819/a8e3e50a-37c9-ce90-61a8-ae3a9b872b86.png)
4. レイクハウスに適当なcsv を読みこみ
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281819/51fe2d7f-8880-3721-6b48-69a914587352.png)
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281819/f4cc4db7-81e5-d3c0-7055-1dc69c145cf6.png)
5. SQL ウェアハウスからクエリしてみます。
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281819/91322d04-5401-da62-47fa-9629d38b1244.png)
6. テーブルを作成してみます。
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281819/c1de4712-a40e-c678-a86c-3b01e36cf963.png)
    レイクハウス上でも自動追加されました。
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281819/07dbd2f7-fd6d-385b-753e-50ece4d91536.png)

以上のように、ハブとなる Azure Data Lake Storage に双方からアクセスしてやることで、Databricks と Fabric でデータを相互連携できます。

この方式では現在 Unity Catalog ミラーリングで ストレージのファイアウォールを通過することができないという制限を回避しながら相互連携が可能です。

スキーマが有効なレイクハウスを使用しない限りは、テーブルの自動追加が難しい点だけが難点ですが、Storage を追加してもよい場合にはこれも有力な選択肢となるかと思います。