簡體   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