spark yarn cluster mode-读取与--files一起传递的文件

dgenwo3n  于 2021-06-03  发布在  Hadoop
关注(0)|答案(4)|浏览(1209)

我正在用yarn cluster master运行我的spark应用程序。
这个应用程序做什么?
外部服务基于对restservice的http请求生成jsonfile
spark需要读取这个文件并在解析json之后做一些工作
想到的最简单的解决方案是使用文件来加载该文件。在yarn cluster模式下,读取文件意味着它必须在hdfs上可用(如果我是对的话?),并且我的文件被复制到如下路径:

/hadoop_user_path/.sparkStaging/spark_applicationId/myFile.json

在这里我当然可以读取它,但是我找不到从任何configuration/sparkenv对象获取此路径的方法。硬编码。在Spark代码中加Spark是个坏主意。
为什么这么简单:

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

无法读取通过--files传递的文件并引发filenotfoundexception?为什么spark只在hadoop\u user\u文件夹中查找文件?

我目前的解决方案是:

就在运行spark之前,我将文件复制到适当的hdfs文件夹中,将文件名作为spark参数传递,从已知路径处理文件,然后在作业完成后从hdfs中删除文件。
我以为把文件作为--files传递会让我忘记保存和删除这个文件。类似于“传递过程”和“忘记”。
如何读取传递的文件--文件?唯一的解决方案是手动创建路径,硬编码“.sparkstaging”文件夹路径?

lokaqttq

lokaqttq1#

来自@hartar的回答对我有用。这是完整的解决方案。
使用--files在spark提交期间添加所需的文件

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));
}
ttvkxqim

ttvkxqim2#

我找到了一个简单的方法。我们使用spark2.3.0对Yarn进行伪分布处理。我们需要从spark查询postgres表,它的配置在属性文件中定义。我使用spark submit的--files属性传递了属性文件。为了读取代码中的文件,我只使用了java.util.properties.propertiesreader类。
我只需要确保加载文件时指定的路径与传入的--files参数相同
e、 g.如果spark submit命令如下所示:spark submit--class--master yarn--deploy mode client--files test/metadata.properties myjar.jar
然后我读取文件的代码将如下所示:properties props=new properties();props.load(新文件inputstream(新文件(“test/metadata.properties”));
希望这对你有帮助。

xxe27gdn

xxe27gdn3#

这个问题写得很含糊。然而,我似乎得到的是,您希望从本地os文件系统的任何位置读取文件,而不仅仅是从hdfs读取文件。
spark使用uri来标识路径,在有效的hadoop/hdfs环境中,它将默认为hdfs。在这种情况下,要指向您的本地操作系统文件系统(例如unix/linux),您可以使用以下命令: file:///home/user/my_file.txt 如果使用rdd读取此文件、以群集模式运行或在任务中访问该文件,则需要注意使用相同的路径手动将该文件复制并分发到群集中的所有节点。这就是为什么它可以很容易地首先把它放在hfs上,或者这就是 --files 选项应该对你有用。
查看有关spark、外部数据集的更多信息。
对于通过 --files 选项,或通过 SparkContext.addFile ,您可以使用 SparkFiles 助手类。

nimxete2

nimxete24#

我和你有同样的问题,事实上,你必须知道,当你发送一个可执行文件和文件,这些是在同一个级别,所以在你的可执行文件,这是足够的,你只要把文件名访问它,因为你的可执行文件是基于自己的文件夹。
您不需要使用sparkfiles或任何其他类。就像readfile(“myfile.json”)那样的方法;

相关问题