我正在尝试使用apache-spark集群模式。 所以我的集群包括我的机器中的驱动程序和主机中的工作者和管理器(单独的机器)。
我使用sparkContext.addFile(filepath)
发送文本文件,其中文件路径是本地计算机中文本文件的路径,我得到以下输出:
INFO Utils: Copying /home/files/data.txt to /tmp/spark-b2e2bb22-487b-412b-831d-19d7aa96f275/userFiles-147c9552-1a77-427e-9b17-cb0845807860/data.txt
INFO SparkContext: Added file /home/files/data.txt at http://192.XX.XX.164:58143/files/data.txt with timestamp 1457432207649
但是当我尝试使用SparkFiles.get("data.txt")
访问同一个文件时,我在驱动程序而不是worker中获取文件的路径。
我正在设置我的文件
SparkConf conf = new SparkConf().setAppName("spark-play").setMaster("spark://192.XX.XX.172:7077");
conf.setJars(new String[]{"jars/SparkWorker.jar"});
JavaSparkContext sparkContext = new JavaSparkContext(conf);
sparkContext.addFile("/home/files/data.txt");
List<String> file =sparkContext.textFile(SparkFiles.get("data.txt")).collect();
我在这里收到FileNotFoundException。
答案 0 :(得分:0)
我认为主要问题是您尝试通过textFile
方法读取文件。 textFile
方法括号内的内容在驱动程序中执行。在工作节点中,仅执行针对RDD运行的代码。当您键入textFile
时,在您的驱动程序中会发生一个RDD对象,其中包含一个简单的关联DAG。但是在工作节点中没有任何反应。
因此,当您尝试收集数据时,系统会要求工作人员通过您传递给textFile
的网址读取该文件,该网址由驱动程序告知。由于您的文件位于驱动程序的本地文件系统中,并且工作节点无法访问它,因此您将获得FileNotFoundException
。
解决方案是通过将文件放入作为HDFS的分布式文件系统或通过ftp将文件提供给工作节点,或者在运行Spark作业之前必须将文件传输到工作节点然后你有将textFile
作为工作文件系统中文件路径的参数。
答案 1 :(得分:0)
我最近遇到了同样的问题,希望我的解决方案可以帮助其他人解决这个问题。
我们知道,当您使用 SparkContext.addFile(<file_path>)
时,它会将文件发送到驱动程序节点(在本例中为您的机器)以及 Spark 集群的工作程序节点中自动创建的工作目录。>
您在使用 SparkFiles.get("data.txt")
的地方共享的代码块正在驱动程序上执行,因此它返回驱动程序上文件的路径,而不是工作程序。但是,任务正在工作程序上运行,并且驱动程序上文件的路径与工作程序上文件的路径不匹配,因为驱动程序和工作程序节点具有不同的工作目录路径。因此,您会得到 FileNotFoundException
。
此问题有一个解决方法,无需使用任何分布式文件系统或 ftp 服务器。您应该将该文件放在主机上的工作目录中。然后,您不使用 SparkContext.get("data.txt")
,而是使用 "./data.txt"
。
List<String> file = sparkContext.textFile("./data.txt").collect();
现在,即使 spark 驱动程序和工作节点之间的工作目录路径不匹配,您也不会遇到 FileNotFoundException
,因为您使用的是相对路径来访问文件。