使用 WASB(旧版)连接到 Azure Blob 存储

Microsoft 已弃用用于 Azure Blob 存储的 Windows Azure Storage Blob 驱动程序 (WASB),以支持 Azure Blob 文件系统驱动程序 (ABFS);请参阅连接到 Azure Data Lake Storage Gen2 和 Blob 存储。 与 WASB 相比,ABFS 有很多好处。请参阅有关 ABFS 的 Azure 文档

本文提供了有关维护使用 WASB 驱动程序的代码的文档。 Databricks 建议对与 Azure Blob 存储的所有连接使用 ABFS。

在 Databricks 中配置 WASB 凭据

WASB 驱动程序允许使用存储帐户访问密钥共享访问签名 (SAS)。 (如果从公共存储帐户读取数据,则无需配置凭据)。

Databricks 建议在需要在 Azure Databricks 中传递凭据时使用机密。 有权访问包含的机密范围的所有用户都可以使用机密。

可以传递凭据:

  • 范围限定为 Spark 配置中的群集
  • 范围限定为笔记本
  • 附加到已装载的目录

Databricks 建议将所有连接升级为使用 ABFS 访问 Azure Blob 存储,后者提供与 WASB 类似的访问模式。 与 Azure Blob 存储交互时,使用 ABFS 获得最佳安全性和性能。

若要配置群集凭据,请在创建群集时设置 Spark 配置属性。 在群集级别设置的凭据可供有权访问该群集的所有用户使用。

若要配置笔记本范围的凭据,请使用 spark.conf.set()。 在笔记本级别传递的凭据可供所有有权访问该笔记本的用户使用。

使用存储帐户访问密钥设置 Azure Blob 存储凭据

存储帐户访问密钥授予对存储帐户中所有容器的完全访问权限。 虽然此模式对于原型制作非常有用,但请避免在生产中使用此模式,以降低与授予对生产数据的无限制访问权限相关的风险。

spark.conf.set(
  "fs.azure.account.key.<storage-account-name>.blob.core.chinacloudapi.cn",
  "<storage-account-access-key>"
)

可以将帐户密钥 URI 升级为使用 ABFS。 有关详细信息,请参阅连接到 Azure Data Lake Storage Gen2 和 Blob 存储

使用共享访问签名 (SAS) 设置 Azure Blob 存储凭据

可以使用 SAS 令牌配置对在特定时间到期的存储帐户中的单个容器的有限访问权限。

spark.conf.set(
  "fs.azure.sas.<container-name>.<storage-account-name>.blob.core.chinacloudapi.cn",
  "<sas-token-for-container>"
)

使用数据帧 API 访问 Azure Blob 存储

Apache Spark 数据帧 API 可以使用在笔记本或群集级别配置的凭据。 所有 WASB 驱动程序 URI 都可指定容器和存储帐户名称。 目录名称是可选的,可以指定相对于容器的多个嵌套目录。

wasbs://<container-name>@<storage-account-name>.blob.core.chinacloudapi.cn/<directory-name>

以下代码示例演示如何使用数据帧 API 和 Databricks 实用程序 (dbutils) 参考与容器内的命名目录进行交互。

df = spark.read.format("parquet").load("wasbs://<container-name>@<storage-account-name>.blob.core.chinacloudapi.cn/<directory-name>")

dbutils.fs.ls("wasbs://<container-name>@<storage-account-name>.blob.core.chinacloudapi.cn/<directory-name>")

若要更新 ABFS 而不是 WASB,请更新 URI。 有关详细信息,请参阅访问 Azure 存储

使用 SQL 访问 Azure Blob 存储

运行 Spark SQL 的笔记本无法访问笔记本会话配置中设置的凭据。

在群集配置中设置帐户访问密钥或 SAS 后,可以对 Azure Blob 存储使用标准 Spark SQL 查询:

-- SQL
CREATE DATABASE <db-name>
LOCATION "wasbs://<container-name>@<storage-account-name>.blob.core.chinacloudapi.cn/";

若要更新 ABFS 而非 WASB,请更新你的 URI;请参阅访问 Azure 存储

将 Azure Blob 存储容器装载到 DBFS

可以将 Azure Blob 存储容器或容器内的文件夹装载到 DBFS。 有关 Databricks 的建议,请参阅在 Azure Databricks 上装载云对象存储

重要

  • Azure Blob 存储支持三种 Blob 类型:块 Blob、追加 Blob 和页 Blob。 只能将块 Blob 装载到 DBFS。
  • 所有用户都对装载到 DBFS 的 Blob 存储容器中的对象具有读写访问权限。
  • 通过群集创建装入点后,该群集的用户可立即访问装入点。 若要在另一个正在运行的群集中使用装入点,则必须在运行的群集上运行 dbutils.fs.refreshMounts(),使新创建的装入点可供使用。

DBFS 使用在创建装入点时提供的凭据来访问已装载的 Blob 存储容器。 如果 Blob 存储容器是使用存储帐户访问密钥装载的,则 DBFS 在访问此装入点时会使用从存储帐户密钥派生的临时 SAS 令牌。

装载 Azure Blob 存储容器

Databricks 建议使用 ABFS 而不是 WASB。 有关使用 ABFS 装载的更多信息,请参阅:使用 ABFS 装载 ADLS Gen2 或 Blob 存储

  1. 若要在容器内装载 Blob 存储容器或文件夹,请使用以下命令:

    Python

    dbutils.fs.mount(
      source = "wasbs://<container-name>@<storage-account-name>.blob.core.chinacloudapi.cn",
      mount_point = "/mnt/<mount-name>",
      extra_configs = {"<conf-key>":dbutils.secrets.get(scope = "<scope-name>", key = "<key-name>")})
    

    Scala

    dbutils.fs.mount(
      source = "wasbs://<container-name>@<storage-account-name>.blob.core.chinacloudapi.cn/<directory-name>",
      mountPoint = "/mnt/<mount-name>",
      extraConfigs = Map("<conf-key>" -> dbutils.secrets.get(scope = "<scope-name>", key = "<key-name>")))
    

    where

    • <storage-account-name> 是你的 Azure Blob 存储帐户的名称。
    • <container-name> 是你的 Azure Blob 存储帐户中某个容器的名称。
    • <mount-name> 是一个 DBFS 路径,表示 Blob 存储容器或该容器中的某个文件夹(在 source 中指定)要装载到 DBFS 中的什么位置。
    • <conf-key> 可以是 fs.azure.account.key.<storage-account-name>.blob.core.chinacloudapi.cnfs.azure.sas.<container-name>.<storage-account-name>.blob.core.chinacloudapi.cn
    • dbutils.secrets.get(scope = "<scope-name>", key = "<key-name>") 获取在机密范围中存储为dbutils.secrets.get(scope = "<scope-name>", key = "<key-name>")的密钥。
  2. 像访问本地文件一样访问容器中的文件,例如:

    Python

    # python
    df = spark.read.format("text").load("/mnt/<mount-name>/...")
    df = spark.read.format("text").load("dbfs:/<mount-name>/...")
    

    Scala

    // scala
    val df = spark.read.format("text").load("/mnt/<mount-name>/...")
    val df = spark.read.format("text").load("dbfs:/<mount-name>/...")
    

    SQL

    -- SQL
    CREATE DATABASE <db-name>
    LOCATION "/mnt/<mount-name>"