2016-12-10 45 views
1

我正在計算在Spark上完成特定作業需要多長時間,在這種情況下,需要多長時間來保存輸出RDD。 RDD的保存包括壓縮它。基準測試中令人感興趣的性能變化Spark代碼

奇怪的是,與第二次執行完全相同的代碼相比,代碼的第一次執行總是比較慢。怎麼會這樣?

的Spark程序如下所示:

JavaPairRDD<String, String> semisorted = wordsAndChar.sortByKey(); 

//First run 
long startTime1 = System.currentTimeMillis(); 
semisorted.saveAsTextFile("testData.txt" + "_output1", org.apache.hadoop.io.compress.DefaultCodec.class); 
long runTime1 = System.currentTimeMillis() - startTime1; 

//Second run 
long startTime2 = System.currentTimeMillis(); 
semisorted.saveAsTextFile("testData.txt" + "_output2", org.apache.hadoop.io.compress.DefaultCodec.class); 
long runTime2 = System.currentTimeMillis() - startTime2; 

sc.stop(); 

火花提交--master本地[1] --class com.john.Test my.jar /用戶/約翰/ TESTDATA。 TXT /用戶/約翰/ testData_output

的輸出是:

runTime1 = 126秒

runTime2 = 82秒

如此大的變化怎麼能有兩個(完全相同)的工作?

+0

RDDs是懶惰的。第一次運行可能被緩存在內存中用於第二次和隨後的運行 –

+0

另外,在單臺機器上運行的兩次運行沒有太多基準 –

+0

@ cricket_007,「兩次運行」,因爲第一次運行時間過長。我甚至有3次以上的跑步。在每種情況下,首次運行速度最慢。這只是「測試」 - 在與某人的機器進行比較之前,需要從一臺機器獲得一個可靠的數字。 – nikk

回答

3

這兩個工作是不一樣的。任何shuffle操作(包括sortByKey)都會創建用作隱式緩存點的shuffle文件。

  • 當您執行第一個作業時,它執行完整的隨機播放和所有前面的操作。

  • 當您執行第二個作業時,它可以讀取洗牌文件並僅執行最後一個階段。

您應該看到與此行爲相對應的skipped stages in the Spark UI

還有另一個變異來源可以在這裏做出貢獻,但其影響應該更小。 Spark中很多與上下文有關的對象都是懶惰的初始化。這些將在第一份工作中初始化。

一般來說,如果你要監視的性能,您可以使用:

  • 手動檢查星火UI。
  • Spark REST API/applications/[app-id]/stages/[stage-id]特別有用)或TaskListener獲取詳細的統計數據。

您還應該:

  • 進行多次試驗,調整結果來糾正初始化過程。
  • unpersist對象,如果需要。
  • 避免可能的混淆因素(例如,由同一個應用程序執行的多個作業不是獨立的,並且可能受到緩存驅逐或GC等多種因素的影響)。
+0

因此,如果這是Spark中的工作之間的內在行爲,比如說我想精確計算並比較這兩段代碼的執行時間。怎麼做?想象一下,在第二步中,我使用了'SnappyCodec',而不是使用'DefaultCodec'。 – nikk