Apache Zeppelin 给出 java.io.FileNotFoundException 尽管该位置存在文件

Apache Zeppelin gives java.io.FileNotFoundException despite file being present in the location

我正在尝试创建一个非常简单的 Zeppelin Notebook,它读取一个 csv 文件并对文件进行分析。但是,我 运行 陷入了一个非常奇怪的错误。尽管文件显示在 ls 命令中,但当我尝试将其读取为 read.csv 时,我得到的是 java.io.FileNotFoundException

ls 命令显示 bank.csv 文件(从上数第 4 个)

但是在尝试读取文件时出现异常。

在本地/独立 Zeppelin 安装中...

很有可能,默认情况下,您的 Zeppelin 笔记本(和底层 Spark 堆栈)配置为在 HDFS 中查找相对文件路径。

因此,您可能需要使用绝对文件路径,并提及您正在处理您的文件系统。

data = spark.csv.read("file:///data/your_path/banks.csv")

Zeppelin集群安装

如果你的笔记本连接到安装了 Spark 的集群,那么访问本地文件系统不是一个好主意(你必须手动将文件部署到集群中的每个节点,保持它们同步......)......好吧,这就是为什么要创建 HDFS。

所以最好的办法就是利用它。将文件放在 HDFS 存储中的某个位置,然后通过 hdfs 从 spark 加载它。

在你的 shell 中:

hdfs dfs -put /file_system_path/banks.csv "/user/zeppelin/banks.csv"

请注意,您的 HDFS 文件可以放置的实际路径将根据您的集群安装而有所不同。

然后 Spark 应该能够加载它:

spark.csv.read("/user/zeppelin/banks.csv")

当然,除了 HDFS 之外,还有其他方法可以做到这一点。例如,Spark 可以连接到 S3,如果它比 HDSF 更适合您,则有可能 (read("s3a://..."))

对于走同一条路的人,即在 Kubernetes 上使用 Helm 安装堆栈,并尝试使用存在于 Zeppelin Pod 上的本地文件,那是 糟糕 糟糕 想法。您最终可能会浪费几个小时尝试深入研究互联网并感到愚蠢。

基本上,它不会按设计工作。所有组件都会尝试在给定的指定路径中找到文件,但它们不会找到它,因为它只存在于 Zeppelin Pod 或 Container 上。我发现最简单的方法是使用 AWS S3,但使用 YMMV。

需要将 AWS 访问密钥导出为所有组件上的环境变量。

- name: AWS_ACCESS_KEY_ID
  value: {{ .Values.Global.Aws.Key }}
- name: AWS_SECRET_ACCESS_KEY
  value: {{ .Values.Global.Aws.Secret }}

然后使用 spark.read.csv('s3a://YOUR_BUCKET_PATH/file.csv') 轻而易举。

虽然测试,但没有 HDFS 的类似方法可能

  1. 创建 PersistentVolumeClaim
  2. 将其安装在所有 pods 的相同路径上,即 Spark Driver、Spark Worker、Zeppelin,并将所有文件放在相同的安装卷中
  3. 使用 file:/// 指令
  4. 提供已安装卷中的绝对文件路径

但同样,这不是一个好主意,因为持久卷不能安装在超过 1 个工作节点上。请记住一个警告。