Dataproc集群中Spark NLP无法读取本地CoNLL 2003数据问题排查
问题
在构建安装了Spark NLP的Dataproc单节点集群后,通过JupyterLab将CoNLL 2003数据下载到/root/original目录,终端执行cd / && head -n 5 original/eng.train可正常查看内容,但运行Spark NLP代码读取该文件时触发java.io.FileNotFoundException。
集群创建命令
gcloud dataproc clusters create s17-sparknlp-experiments \ --enable-component-gateway \ --region us-west1 \ --metadata 'PIP_PACKAGES=google-cloud-storage spark-nlp==2.5.5' \ --zone us-west1-a \ --single-node \ --master-machine-type n1-standard-4 \ --master-boot-disk-size 35 \ --image-version 1.5-debian10 \ --initialization-actions gs://dataproc-initialization-actions/python/pip-install.sh \ --optional-components JUPYTER,ANACONDA \ --project my-project
测试代码
from pyspark.ml import Pipeline from pyspark.sql import SparkSession from sparknlp.annotator import * from sparknlp.base import * from sparknlp.common import * from sparknlp.training import CoNLL import sparknlp spark = sparknlp.start() print("Spark NLP version: ", sparknlp.version()) # 输出2.4.4 print("Apache Spark version: ", spark.version) # 输出2.4.8 # 环境信息: # Python 3.6.13 :: Anaconda, Inc. # openjdk version "1.8.0_312" # OpenJDK Runtime Environment (Temurin)(build 1.8.0_312-b07) # OpenJDK 64-Bit Server VM (Temurin)(build 25.312-b07, mixed mode) training_data = CoNLL().readDataset(spark, 'original/eng.train') # 路径与终端执行时一致 training_data.show()
报错信息
Py4JJavaError: An error occurred while calling o87.readDataset. : java.io.FileNotFoundException: file or folder: original/eng.train not found ...(省略栈追踪信息)
可能的原因及解决办法
Spark工作目录与终端当前目录不匹配
终端执行命令时处于/目录,所以original/eng.train指向/original/eng.train,但Spark应用的默认工作目录并非/,而是JupyterLab的启动目录(通常为/home/jupyter或用户工作目录)。此时相对路径original/eng.train会被解析为Spark工作目录下的路径,自然找不到文件。
解决:使用绝对路径指定文件位置,将代码中的路径改为'/root/original/eng.train'。Spark进程无权限访问/root目录
Dataproc中Spark执行进程以yarn或spark用户身份运行,而/root是root用户的私有目录,其他用户无读取权限。即使文件存在,Spark进程也无法访问。
解决:- 将文件移动到全局可访问目录(如
/tmp),修改代码路径为'/tmp/original/eng.train'; - 执行
chmod -R 755 /root/original,开放目录及文件的读取权限给其他用户。
- 将文件移动到全局可访问目录(如
未采用分布式存储路径
Dataproc集群推荐将数据存储在GCS(Google Cloud Storage)而非本地磁盘,即使是单节点集群,Spark的文件读取逻辑仍优先适配分布式存储。当前文件存放在主节点本地磁盘,不符合Spark的访问预期。
解决:将文件上传到GCS桶,例如gs://your-bucket-name/conll/eng.train,代码中使用该路径读取。
内容的提问来源于stack exchange,提问作者David Espinosa

