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 的类似方法可能
- 创建
PersistentVolumeClaim
- 将其安装在所有 pods 的相同路径上,即 Spark Driver、Spark Worker、Zeppelin,并将所有文件放在相同的安装卷中
- 使用
file:///
指令 提供已安装卷中的绝对文件路径
但同样,这不是一个好主意,因为持久卷不能安装在超过 1 个工作节点上。请记住一个警告。
我正在尝试创建一个非常简单的 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 的类似方法可能
- 创建
PersistentVolumeClaim
- 将其安装在所有 pods 的相同路径上,即 Spark Driver、Spark Worker、Zeppelin,并将所有文件放在相同的安装卷中
- 使用
file:///
指令 提供已安装卷中的绝对文件路径
但同样,这不是一个好主意,因为持久卷不能安装在超过 1 个工作节点上。请记住一个警告。