繁体   English   中英

Spark yarn-cluster模式-读取通过--files传递的文件

[英]Spark yarn-cluster mode - read file passed with --files

我正在使用yarn-cluster master运行我的spark应用程序。

该应用程序做什么?

  1. 外部服务根据对RESTService的HTTP请求生成jsonFile
  2. Spark需要在解析JSON后读取该文件并做一些工作

想到的最简单的解决方案是使用--files加载该文件。 在yarn-cluster模式下,读取文件意味着该文件必须在hdfs上可用(如果我对?),并且我的文件将被复制到以下路径:

/hadoop_user_path/.sparkStaging/spark_applicationId/myFile.json

我当然可以在哪里读取它,但是我找不到从任何配置/ SparkEnv对象获取此路径的方法。 在火花代码中进行硬编码.sparkStaging似乎是一个坏主意。

为什么简单:

val jsonStringData = spark.textFile(myFileName)
sqlContext.read.json(jsonStringData)

无法读取通过--files传递的文件并抛出FileNotFoundException? 为什么Spark只在hadoop_user_folder中查找文件?

我现在可以使用的解决方案:

在运行Spark之前,我将文件复制到正确的hdfs文件夹,将文件名作为Spark参数传递,从已知路径处理文件,完成作业后,我从hdfs删除文件。

我认为将文件作为--files传递会让我忘记保存和删除此文件。 就像通过过程忘记了。

您如何读取通过--files传递的文件? 唯一的解决方案是手动创建路径,对“ .sparkStaging”文件夹路径进行硬编码?

这个问题写得很模棱两可。 但是,据我看来,您想从本地OS文件系统的任何位置读取文件,而不仅仅是从HDFS中读取文件。

Spark使用URI标识路径,并且在有效的Hadoop / HDFS环境可用时,它将默认为HDFS。 在这种情况下,要指向您的本地操作系统文件系统,例如在UNIX / LINUX中,您可以使用以下命令:

file:///home/user/my_file.txt

如果您使用RDD读取此文件,以yarn-cluster模式运行,或者在任务中访问该文件,则需要注意使用以下方法手动将文件复制并分发到群集中的所有节点:相同的路径。 这就是让它首先放在hfs上变得容易的原因,或者--files选项应该为您完成的事情。

查看有关Spark,外部数据集的更多信息。

对于通过--files选项添加或通过SparkContext.addFile添加的任何文件,您可以使用SparkFiles帮助器类获取有关其位置的信息。

@hartar的回答对我有用。 这是完整的解决方案。

使用--files在提交火花期间添加所需的文件

spark-submit --name "my_job" --master yarn --deploy-mode cluster --files /home/xyz/file1.properties,/home/xyz/file2.properties --class test.main /home/xyz/my_test_jar.jar

在主方法中获取spark会话

SparkSession ss = new SparkSession.Builder().getOrCreate();

由于我只对.properties文件感兴趣,因此我对其进行过滤,如果您知道要读取的文件名,则可以直接在FileInputStream中使用它。

spark.yarn.dist.files会将其存储为file:/home/xyz/file1.properties,file:/home/xyz/file2.properties,因此用(,)和(/)分割字符串,这样我就可以消除其余内容(文件名除外)。

String[] files = Pattern.compile("/|,").splitAsStream(ss.conf().get("spark.yarn.dist.files")).filter(s -> s.contains(".properties")).toArray(String[]::new);

//load all files to Property                
for (String f : files) {
    props.load(new FileInputStream(f));
}

我遇到了与您相同的问题,实际上,您必须知道,在发送可执行文件和文件时,它们处于同一级别,因此在您的可执行文件中,只需将文件名放在Access中就足够了,因为可执行文件基于其自己的文件夹。

您不需要使用sparkFiles或任何其他类。 就像readFile(“ myFile.json”);这样的方法;

我遇到了一种简单的方法。 我们在伪分布模式下的纱线上使用Spark 2.3.0。 我们需要从spark查询一个postgres表,其配置在属性文件中定义。 我使用spark提交的--files属性传递了属性文件。 要在我的代码中读取文件,我只使用了java.util.Properties.PropertiesReader类。

我只需要确保加载文件时指定的路径与--files参数中传递的路径相同

例如,如果spark提交命令看起来像:spark-submit --class --master yarn --deploy-mode client-files test / metadata.properties myjar.jar

然后,我读取文件的代码将如下所示:Properties props = new Properties(); props.load(new FileInputStream(new File(“ test / metadata.properties”))));

希望对您有所帮助。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM