java.lang.ClassNotFoundException:找不到类 org.apache.hadoop.fs.azurebfs.SecureAzureBlobFileSystem

Ali*_*bas 5 java hadoop apache-spark kubernetes azure-data-lake-gen2

我是 Spark 和 Kubernetes 世界的新手。我使用 docker-image-tool.sh 实用程序使用与 Hadoop 3.2 捆绑在一起的官方 Spark 3.0.1 构建了 Spark docker 映像。

我还为 Jupyter Notebook 创建了另一个 docker 映像,并尝试在客户端模式下在 Kubernetes 上运行 Spark。我首先将 Jupyter 笔记本作为 pod 运行,使用 kubectl 进行端口转发,并从我的系统 localhost:8888 访问笔记本 UI。一切似乎都运转良好。我能够从笔记本成功运行命令。

现在,我尝试使用Hadoop ABFS 连接器从我的笔记本访问 Azure Data Lake Gen2 。我将 Spark 上下文设置如下。

from pyspark import SparkContext, SparkConf
from pyspark.sql import SparkSession
# Create Spark config for our Kubernetes based cluster manager


sparkConf = SparkConf()
sparkConf.setMaster("k8s://https://kubernetes.default.svc.cluster.local:443")
sparkConf.setAppName("spark")
sparkConf.set("spark.kubernetes.container.image", "<<my_repo>>/spark-py:latest")
sparkConf.set("spark.kubernetes.namespace", "spark")
sparkConf.set("spark.executor.instances", "3")
sparkConf.set("spark.executor.cores", "2")
sparkConf.set("spark.driver.memory", "512m")
sparkConf.set("spark.executor.memory", "512m")
sparkConf.set("spark.kubernetes.pyspark.pythonVersion", "3")
sparkConf.set("spark.kubernetes.authenticate.driver.serviceAccountName", "spark")
sparkConf.set("spark.kubernetes.authenticate.serviceAccountName", "spark")
sparkConf.set("spark.driver.port", "29413")
sparkConf.set("spark.driver.host", "my-notebook-deployment.spark.svc.cluster.local")

sparkConf.set("fs.azure.account.auth.type", "SharedKey")
sparkConf.set("fs.azure.account.key.<<storage_account_name>>.dfs.core.windows.net","<<account_key>>")

spark = SparkSession.builder.config(conf=sparkConf).getOrCreate()
Run Code Online (Sandbox Code Playgroud)

然后我运行以下命令来读取 ADLS 位置中存在的 csv 文件

df = spark.read.csv("abfss://<<container>>@<<storage_account>>.dfs.core.windows.net/")
Run Code Online (Sandbox Code Playgroud)

运行它时,我收到错误 Py4JJavaError:调用 o443.csv 时发生错误。:java.lang.RuntimeException:java.lang.ClassNotFoundException:找不到类org.apache.hadoop.fs.azurebfs.SecureAzureBlobFileSystem

经过一些研究,我发现我必须明确包含 hadoop-azure jar 才能使用适当的类。我从这里下载了jar ,将其放入/spark-3.0.1-bin-hadoop3.2/jars文件夹中并再次构建了图像。

不幸的是我仍然收到这个错误。我手动验证了 jar 文件确实存在于 docker 映像中并且包含该类org.apache.hadoop.fs.azurebfs.SecureAzureBlobFileSystem

我查看了文件夹中的entrypoint.sh spark-3.0.1-bin-hadoop3.2\kubernetes\dockerfiles\spark,它是我们的spark docker 映像的入口点。它将文件夹中存在的所有包添加spark-3.0.1-bin-hadoop3.2\jar\到类路径中。

# If HADOOP_HOME is set and SPARK_DIST_CLASSPATH is not set, set it here so Hadoop jars are available to the executor.
# It does not set SPARK_DIST_CLASSPATH if already set, to avoid overriding customizations of this value from elsewhere e.g. Docker/K8s.
if [ -n "${HADOOP_HOME}"  ] && [ -z "${SPARK_DIST_CLASSPATH}"  ]; then
  export SPARK_DIST_CLASSPATH="$($HADOOP_HOME/bin/hadoop classpath)"
fi

if ! [ -z ${HADOOP_CONF_DIR+x} ]; then
  SPARK_CLASSPATH="$HADOOP_CONF_DIR:$SPARK_CLASSPATH";
fi
Run Code Online (Sandbox Code Playgroud)

根据我的理解,spark 应该能够通过任何附加的 setJar 配置在其类路径中找到该类。

有人可以指导我如何解决这个问题吗?我可能在这里遗漏了一些非常基本的东西。

Ali*_*bas 1

看起来我需要在运行 Jupyter Notebook 并充当 Spark 驱动程序的 Docker 映像中添加 hadoop-azure 包。这样做后它按预期工作。