Databricksへのクラウドオブジェクトストレージのマウント

重要

マウントは、従来のアクセスパターンです。Databricksでは、すべてのデータアクセスの管理にUnity Catalogの使用を推奨しています。「Unity Catalogを使用したクラウドオブジェクトストレージへの接続」を参照してください。

Databricksを使用すると、ユーザーはクラウドオブジェクトストレージを Databricksファイルシステム(DBFS)にマウントして、クラウドの概念に慣れていないユーザーのデータアクセスパターンを簡素化できます。マウントされたデータはUnity Catalogでは機能しないため、Databricksではマウントの使用から移行し、代わりにUnity Catalogを使用してデータガバナンスを管理することをお勧めします。

Databricks はクラウドオブジェクトストレージをどのようにマウントしますか?

Databricks マウントは、ワークスペースとクラウドオブジェクトストレージの間にリンクを作成します。これにより、Databricks ファイル システムを基準としたわかりやすいファイル パスを使用して、クラウドオブジェクトストレージを操作できるようになります。マウントは、/mnt ディレクトリの下に、次の情報が格納されたローカルエイリアスを作成することによって機能します。

  • クラウドオブジェクトストレージの場所。

  • ストレージアカウントまたはコンテナーに接続するためのドライバー仕様。

  • データにアクセスするために必要なセキュリティ資格情報。

ストレージをマウントする構文はどのようなものですか?

sourceは、オブジェクトストレージの URI を指定します(オプションでセキュリティ資格情報をエンコードすることもできます)。mount_pointは、/mntディレクトリのローカルパスを指定します。一部のオブジェクトストレージソースは、オプションのencryption_type引数をサポートしています。一部のアクセスパターンでは、追加の構成仕様を辞書としてextra_configsに渡すことができます。

注:

Databricksでは、extra_configs を使用してマウント固有のSparkとHadoopの設定をオプションとして設定することを推奨しています。これにより、設定がクラスターやセッションではなくマウントに関連付けられます。

dbutils.fs.mount(
  source: str,
  mount_point: str,
  encryption_type: Optional[str] = "",
  extra_configs: Optional[dict[str:str]] = None
)

設定が不適切な場合、ワークスペース内のすべてのユーザーに提供されるアクセスが安全でなくなる可能性があるため、データマウントの設定や変更の前に、ワークスペースおよびクラウドの管理者に確認してください。

注:

この記事で説明したアプローチに加えて、Databricks Terraformプロバイダとdatabricks_mountを使用すると、バケットのマウントを自動化できます。

マウントポイントのアンマウント

マウントポイントをアンマウントするには、次のコマンドを使用します。

dbutils.fs.unmount("/mnt/<mount-name>")

警告

エラーを回避するため、他のジョブがマウントポイントの読み取りまたは書き込みを行っている間は、絶対にマウントポイントを変更しないでください。マウントを変更した後は、実行中の他のすべてのクラスターで必ず dbutils.fs.refreshMounts() を実行して、マウントの更新を伝播させてくださいrefreshMountsコマンド(dbutils.fs.refreshMounts)を参照してください。

S3 バケットをマウントする

S3バケットは、DBFSを使用してマウントできます。マウントはS3の場所へのポインタなので、データがローカルで同期されることはありません。

クラスターからマウントポイントが作成されると、そのクラスターのユーザーはすぐにそのマウントポイントにアクセスできます。稼働中の別のクラスターでマウントポイントを使用するには、その稼働中のクラスターで dbutils.fs.refreshMounts() を実行して、新しく作成したマウントポイントを使用できるようにする必要があります。

S3 バケットをマウントする方法として、次のようなものがあります。

AWSインスタンスプロファイルを使用したバケットのマウント

AWSインスタンスプロファイルを使用して、S3バケットの認証と認可を管理できます。バケット内のオブジェクトへのアクセスは、インスタンスプロファイルに付与された権限によって決まります。ロールに書き込み権限がある場合、マウントポイントのユーザーはバケットにオブジェクトを書き込むことができます。ロールに読み取り権限がある場合、マウントポイントのユーザーはバケット内のオブジェクトを読み取ることができます。

  1. インスタンスプロファイルを使用してクラスターを設定します。

  2. バケットをマウントします。

    aws_bucket_name = "<aws-bucket-name>"
    mount_name = "<mount-name>"
    dbutils.fs.mount(f"s3a://{aws_bucket_name}", f"/mnt/{mount_name}")
    display(dbutils.fs.ls(f"/mnt/{mount_name}"))
    
    val AwsBucketName = "<aws-bucket-name>"
    val MountName = "<mount-name>"
    
    dbutils.fs.mount(s"s3a://$AwsBucketName", s"/mnt/$MountName")
    display(dbutils.fs.ls(s"/mnt/$MountName"))
    

AWSキーを使用したバケットのマウント

AWSキーを使用してバケットをマウントできます。

重要

キーを使用してS3バケットをマウントすると、すべてのユーザーに、S3バケット内のすべてのオブジェクトへの読み取りと書き込みのアクセス権が付与されます。

次の例では、Databricksシークレットを使用してキーを格納しています。シークレットキーはURLエスケープする必要があります

access_key = dbutils.secrets.get(scope = "aws", key = "aws-access-key")
secret_key = dbutils.secrets.get(scope = "aws", key = "aws-secret-key")
encoded_secret_key = secret_key.replace("/", "%2F")
aws_bucket_name = "<aws-bucket-name>"
mount_name = "<mount-name>"

dbutils.fs.mount(f"s3a://{access_key}:{encoded_secret_key}@{aws_bucket_name}", f"/mnt/{mount_name}")
display(dbutils.fs.ls(f"/mnt/{mount_name}"))
val AccessKey = dbutils.secrets.get(scope = "aws", key = "aws-access-key")
// Encode the Secret Key as that can contain "/"
val SecretKey = dbutils.secrets.get(scope = "aws", key = "aws-secret-key")
val EncodedSecretKey = SecretKey.replace("/", "%2F")
val AwsBucketName = "<aws-bucket-name>"
val MountName = "<mount-name>"

dbutils.fs.mount(s"s3a://$AccessKey:$EncodedSecretKey@$AwsBucketName", s"/mnt/$MountName")
display(dbutils.fs.ls(s"/mnt/$MountName"))

インスタンスプロファイルとAssumeRoleポリシーを使用したバケットのマウント

まず、AssumeRoleポリシーでAccessクロスアカウントS3バケットを設定する必要があります。

extraConfigsでS3オプションを設定しながらバケットをマウントします。

dbutils.fs.mount("s3a://<s3-bucket-name>", "/mnt/<s3-bucket-name>",
  extra_configs = {
    "fs.s3a.credentialsType": "AssumeRole",
    "fs.s3a.stsAssumeRole.arn": "arn:aws:iam::<bucket-owner-acct-id>:role/MyRoleB",
    "fs.s3a.canned.acl": "BucketOwnerFullControl",
    "fs.s3a.acl.default": "BucketOwnerFullControl"
  }
)
dbutils.fs.mount("s3a://<s3-bucket-name>", "/mnt/<s3-bucket-name>",
  extraConfigs = Map(
    "fs.s3a.credentialsType" -> "AssumeRole",
    "fs.s3a.stsAssumeRole.arn" -> "arn:aws:iam::<bucket-owner-acct-id>:role/MyRoleB",
    "fs.s3a.canned.acl" -> "BucketOwnerFullControl",
    "fs.s3a.acl.default" -> "BucketOwnerFullControl"
  )
)

S3バケット内のデータの暗号化

Databricksは、サーバー側の暗号化を使用したデータの暗号化をサポートしています。このセクションでは、DBFS経由でS3にファイルを書き込むときにサーバー側の暗号化を使用する方法について説明します。Databricksは、Amazon S3で管理される暗号化キー(SSE-S3)AWS KMSで管理される暗号化キー(SSE-KMS)をサポートしています。

SSE-S3 を使用したファイルの書き込み

  1. SSE-S3を使用してS3バケットをマウントするには、次のコマンドを実行します。

    dbutils.fs.mount(s"s3a://$AccessKey:$SecretKey@$AwsBucketName", s"/mnt/$MountName", "sse-s3")
    
  2. SSE-S3を使用して対応するS3バケットにファイルを書き込むには、次のコマンドを実行します。

    dbutils.fs.put(s"/mnt/$MountName", "<file content>")
    

SSE-KMS を使用したファイルの書き込み

  1. 暗号化タイプとしてsse-kmsまたはsse-kms:$KmsKeyを渡し、ソースディレクトリをマウントします。

    • デフォルトのKMSマスターキーを使用してSSE-KMSでS3バケットをマウントするには、次のコマンドを実行します。

      dbutils.fs.mount(s"s3a://$AccessKey:$SecretKey@$AwsBucketName", s"/mnt/$MountName", "sse-kms")
      
    • 特定のKMSキーを使用してSSE-KMSでS3バケットをマウントするには、次のコマンドを実行します。

      dbutils.fs.mount(s"s3a://$AccessKey:$SecretKey@$AwsBucketName", s"/mnt/$MountName", "sse-kms:$KmsKey")
      
  2. SSE-KMS を使用して S3 バケットにファイルを書き込むには、次のコマンドを実行します。

    dbutils.fs.put(s"/mnt/$MountName", "<file content>")
    

Databricks コミットサービスを使用した S3 バケットのマウント

S3に格納されている特定のテーブルに複数のクラスターまたはワークロードから同時に書き込む場合、DatabricksではDatabricks S3コミットサービスを設定することをお勧めしています。その際は、ノートブックコードでバケットをマウントし、AssumeRole設定を追加する必要があります。この手順は、DBFSマウントにのみ必要であり、ワークスペースのルートS3バケット内のDBFSルートストレージにアクセスする場合には必要ありません。次の例ではPythonを使用しています。


# If other code has already mounted the bucket without using the new role, unmount it first
dbutils.fs.unmount("/mnt/<mount-name>")

# mount the bucket and assume the new role
dbutils.fs.mount("s3a://<bucket-name>/", "/mnt/<mount-name>", extra_configs = {
    "fs.s3a.credentialsType": "AssumeRole",
    "fs.s3a.stsAssumeRole.arn": "<role-arn>"
})

ABFS を使用した ADLS Gen2 または Blob ストレージのマウント

認証にMicrosoft Entra IDアプリケーションサービスプリンシパルを使用して、Azureストレージアカウントにデータをマウントできます。詳細については、「 サービスプリンシパルとMicrosoft Entra ID(Azure Active Directory)を使用してストレージにアクセスする」を参照してください。

重要

  • Databricks ワークスペースのすべてのユーザーは、マウントされた ADLS Gen2 アカウントにアクセスできます。ADLS Gen2 アカウントへのアクセスに使用するサービスプリンシパルは、その ADLS Gen2 アカウントへのアクセスのみを許可し、他の Azure リソースへのアクセスは許可しないようにする必要があります。

  • クラスターを介してマウントポイントを作成すると、クラスターユーザーはすぐにそのマウントポイントにアクセスできます。実行中の別のクラスターでマウントポイントを使用するには、その実行中のクラスターでdbutils.fs.refreshMounts()を実行して、新しく作成したマウントポイントを使用できるようにする必要があります。

  • ジョブの実行中にマウントポイントをアンマウントすると、エラーが発生する可能性があります。本番運用ジョブが処理の一環としてストレージをアンマウントしないことを確認してください。

  • シークレットを使用するマウントポイントは自動的には更新されません。マウントされたストレージが、ローテーション、期限切れ、または削除されたシークレットに依存している場合、401 Unauthorized などのエラーが発生する可能性があります。 このようなエラーを解決するには、ストレージをアンマウントして再マウントする必要があります。

  • ABFSエンドポイントを使用してAzure Data Lake Storage Gen2ストレージアカウントを正しくマウントするには、階層型名前空間(HNS)を有効にする必要があります。

ノートブックで以下を実行して認証し、マウントポイントを作成します。

configs = {"fs.azure.account.auth.type": "OAuth",
          "fs.azure.account.oauth.provider.type": "org.apache.hadoop.fs.azurebfs.oauth2.ClientCredsTokenProvider",
          "fs.azure.account.oauth2.client.id": "<application-id>",
          "fs.azure.account.oauth2.client.secret": dbutils.secrets.get(scope="<scope-name>",key="<service-credential-key-name>"),
          "fs.azure.account.oauth2.client.endpoint": "https://login.microsoftonline.com/<directory-id>/oauth2/token"}

# Optionally, you can add <directory-name> to the source URI of your mount point.
dbutils.fs.mount(
  source = "abfss://<container-name>@<storage-account-name>.dfs.core.windows.net/",
  mount_point = "/mnt/<mount-name>",
  extra_configs = configs)
val configs = Map(
  "fs.azure.account.auth.type" -> "OAuth",
  "fs.azure.account.oauth.provider.type" -> "org.apache.hadoop.fs.azurebfs.oauth2.ClientCredsTokenProvider",
  "fs.azure.account.oauth2.client.id" -> "<application-id>",
  "fs.azure.account.oauth2.client.secret" -> dbutils.secrets.get(scope="<scope-name>",key="<service-credential-key-name>"),
  "fs.azure.account.oauth2.client.endpoint" -> "https://login.microsoftonline.com/<directory-id>/oauth2/token")
// Optionally, you can add <directory-name> to the source URI of your mount point.
dbutils.fs.mount(
  source = "abfss://<container-name>@<storage-account-name>.dfs.core.windows.net/",
  mountPoint = "/mnt/<mount-name>",
  extraConfigs = configs)

置き換え

  • <application-id> を、Azure Active Directoryアプリケーションのアプリケーション (クライアント) IDに置き換えます。

  • <scope-name> を、Databricksシークレットスコープ名に置き換えます。

  • <service-credential-key-name> を、クライアントシークレットが格納されたキーの名前に置き換えます。

  • <directory-id> を、Azure Active Directoryアプリケーションのディレクトリ (テナント) IDに置き換えます。

  • <container-name> を、ADLS Gen2 ストレージ アカウント内のコンテナーの名前に置き換えます。

  • <storage-account-name> を、ADLS Gen2 ストレージアカウント名に置き換えます。

  • <mount-name> を、DBFS 内の目的のマウントポイントの名前に置き換えます。