You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Azure Databricks Notebook读取Azure Blob Storage文件挂起解决方法

问题原因

本地环境代码运行正常但Azure Databricks环境永久挂起,均为Databricks运行时和本地环境的差异导致,常见触发场景如下:

  • 网络连通性被静默拦截:如果Databricks工作区部署在自定义VNet下,未配置存储账户服务终结点、NSG/防火墙规则拦截了集群节点到Blob存储443端口的出站流量,或是存储账户防火墙允许列表未加入Databricks集群的出口网段/公网IP,TCP连接会被中间设备静默丢弃。而Azure Blob SDK默认无连接超时配置,会持续重试TCP握手,表现为进程永久挂起,不会抛出异常。
  • 依赖类路径冲突:Databricks运行时自带了内置版本的Azure Storage SDK、Netty网络依赖,如果代码调用了和运行时内置版本不兼容的SDK包,会出现HTTP客户端初始化死锁、底层请求无调度资源的问题,这类问题不会抛出类冲突、类不存在的报错,仅会表现为请求卡住。
  • SDK默认客户端兼容性问题:新版Azure Blob SDK默认使用Reactor Netty异步客户端,在Databricks Notebook的主线程类加载上下文下,偶发异步线程调度死锁,导致打开输入流的请求永远无法拿到执行资源。
  • 额外注意:示例代码中containerName参数占位符多写了一个右尖括号>,替换真实参数时如果带入了多余符号,也可能出现非预期的请求异常。
排查解决步骤

按以下顺序逐步排查,可覆盖99%以上的同类问题:

  1. 先验证基础网络连通性
    在Notebook新建单元格执行如下Shell命令,跳过SDK直接测试节点到存储的连通性:
    %sh
    curl -v -m 15 "https://<storage-account>.blob.core.windows.net/<container-name>/<blob-name>?<sas-token>"
    
    • 如果命令执行超时、报Connection refused,直接定位为网络规则问题:VNet注入的工作区需要给子网配置Microsoft.Storage服务终结点,或将子网加入存储账户防火墙允许列表;公网访问的工作区需要把集群出口公网IP加入存储账户允许列表,同时检查集群关联NSG是否放开443端口到存储服务的出站规则。
    • 如果命令正常返回Blob内容,说明网络无问题,继续往下排查。
  2. 解决依赖冲突
    在Notebook最开头新增依赖配置单元格,显式引入经过兼容性验证的SDK版本,避免和运行时内置依赖冲突,执行后重启集群内核:
    %dep
    z.add("com.azure:azure-storage-blob:12.23.0")
    z.add("com.azure:azure-core-http-netty:1.43.0")
    
  3. 显式配置SDK超时与HTTP客户端,规避默认配置死锁
    不要使用SDK默认的无超时配置,手动初始化HTTP客户端并设置合理超时,修改后的可运行代码如下:
    import com.azure.storage.blob.BlobClientBuilder
    import com.azure.core.http.netty.NettyAsyncHttpClientBuilder
    import java.io.InputStream
    import java.time.Duration
    
    // 显式初始化HTTP客户端,配置短超时避免永久挂起
    val httpClient = new NettyAsyncHttpClientBuilder()
      .connectTimeout(Duration.ofSeconds(10))
      .responseTimeout(Duration.ofSeconds(30))
      .build()
    
    val input: InputStream = new BlobClientBuilder()
          .endpoint("https://<storage-account>.blob.core.windows.net")
          .sasToken("<sas-token>")
          .containerName("<container-name>") // 替换时注意删除多余的>符号
          .blobName("<blob-name>")
          .httpClient(httpClient)
          .buildClient()
          .openInputStream()
    
  4. 兼容方案兜底
    如果上述方案仍有问题,可直接使用Databricks内置的Hadoop ABFS客户端访问存储,无需额外引入第三方SDK,完全兼容Databricks运行时环境:
    // 配置SAS认证
    spark.conf.set(
      "fs.azure.sas.<container-name>.<storage-account>.blob.core.windows.net",
      "<sas-token>"
    )
    // 读取Blob获取输入流
    val inputStream = spark.read.format("binaryFile")
      .load("wasbs://<container-name>@<storage-account>.blob.core.windows.net/<blob-name>")
      .select("content")
      .head()
      .getAs[Array[Byte]](0)
      .inputStream()
    

内容的提问来源于stack exchange,提问作者Ryan Lindbeck

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 05:45:39