我当前正在尝试从 Databricks 文件系统 (DBFS) 读取和显示文件,但遇到了问题。这是我使用的代码:
file_path = "/dbfs/cluster-logs/use_case/default_job_cluster/cluster_id/init_scripts/cluster_id/20240801_proxy-init.sh.stderr.log"
with open(file_path, 'r') as file:
contents = file.read()
print(contents)
但是,有趣的是我收到以下错误:
bash: line 11: /Volumes/landing/default/artifacts/projects/use_case/databricks/scripts/proxy-init.sh: No such file or directory
如您所见,路径与原始输入不匹配。 最后,我能够使用以下代码正确读取并显示日志文件内容:
file_path = "/dbfs/cluster-logs/use_case/default_job_cluster/cluster_id/init_scripts/cluster_id/20240801_proxy-init.sh.stderr.log"
from pyspark.sql import functions as F
from pyspark.sql.functions import collect_list
if dbutils.fs.ls(file_path):
file_df_to_check = spark.read.text(file_path).agg(collect_list("value").alias("all_lines"))
display(file_df_to_check)
问题:
- 为什么第一个代码片段会产生引用卷路径的错误?
- 它是什么意思文档中的意思是 DBFS 为卷提供了 方案 ?那么第一个片段不应该工作吗?
- 为什么只能使用 Spark 读取文件,而不能使用标准的 Python open 函数读取文件?
感谢您的帮助。
让我们分解一下 Databricks 文件系统 (DBFS) 和卷,以澄清这些概念以及代码的行为方式。
- 错误和路径不匹配
你看到的错误
/Volumes/landing/default/artifacts/projects/use_case/databricks/scripts/proxy-init.sh
实际上暴露了你 Databricks 环境的后台。Databricks 集群在节点上运行,这些节点可能具有自己的本地文件系统。你在启动集群时选择的路径(在本例中为
/Volumes/landing/...
)似乎已安装到 DBFS 上。
当你在 Databricks 笔记本中使用
open(file_path, 'r')
时,你正在使用
Python
的
open
函数,该函数在
Databricks 集群节点
的本地文件系统上运行。初始代码段中的
file_path
指向 DBFS 位置,但错误消息表明代码尝试在本地安装的卷中访问
类似
的路径(这很可能是在你的 Databricks 工作区中镜像 DBFS 位置的自动安装)。
- DBFS 卷方案
你在 Microsoft 文档中提到的“DBFS 卷方案”指的是一种在 Databricks 中更持久、更协作地管理数据的结构化方法。它们与这个特定问题没有直接关系。它们提供了在 DBFS 中组织和管理数据的强大方法,但不会改变
open
函数的行为。
- 使用 Spark 与 Python 读取
你*
可以
使用标准 Python 的
open
函数读取 DBFS 文件,但你必须使用
dbutils.fs.cp()
或
dbutils.fs.move()
将文件复制到本地文件系统或使用
dbutils
API 读取文件:
file_path_dbfs = "/dbfs/cluster-logs/use_case/default_job_cluster/cluster_id/init_scripts/cluster_id/20240801_proxy-init.sh.stderr.log"
local_file_path = "/tmp/20240801_proxy-init.sh.stderr.log"
dbutils.fs.cp(file_path_dbfs, local_file_path)
with open(local_file_path, 'r') as file:
contents = file.read()
print(contents)
但是,Spark(你正在使用的方法)通常是 Databricks 中处理文件的推荐方法,原因如下:
-
分布式处理:
Spark 旨在跨集群处理大量数据。当你使用
spark.read.text()
时,Spark 会将文件拆分,并在多个节点上并行处理。这对于大型文件来说效率要高得多。 - 数据框架: Spark 将数据加载到数据框架中,为转换、分析和轻松使用其他 Spark 功能提供了一种结构化格式。
总之
-
你看到的错误是因为
open
函数在 Databricks 集群节点的本地文件系统上运行,而不是在 DBFS 上运行。 -
虽然 DBFS 卷提供了组织数据的方法,但它们不影响
open
函数的此特定行为。 -
你可以使用
dbutils.fs
API 或将文件复制到本地文件系统来使用 Python 的open
函数读取 DBFS 文件,但通常建议使用 Spark 读取和处理数据以获得更好的性能和集成。