基准测试Spark代码中有趣的性能变化

时间:2016-12-10 18:53:10

标签: apache-spark benchmarking

我正在计算在Spark上完成特定作业需要多长时间,在这种情况下保存输出RDD需要多长时间。保存RDD涉及压缩它。

奇怪的是,与完全相同的代码片段的第二次执行相比,第一次执行代码总是更慢。怎么会这样?

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();
  

spark-submit --master local [1] --class com.john.Test my.jar   /user/john/testData.txt / user / john / testData_output

输出结果为:

  

runTime1 = 126秒

     

runTime2 = 82秒

如此大的变化如何才能完成两个(完全相同的)工作?

1 个答案:

答案 0 :(得分:3)

这两项工作并不相同。任何shuffle操作(包括sortByKey)都会创建shuffle文件,这些文件充当隐式缓存点。

  • 当您执行第一个作业时,它会执行完整的随机播放和所有前面的操作。

  • 执行第二个作业时,它可以读取随机文件并仅执行最后一个步骤。

您应该看到与此行为相对应的skipped stages in the Spark UI

还有另一种变异来源可以在这里起作用,但其影响应该更小。 Spark中许多与上下文相关的对象都是懒惰地初始化的。这些将在第一份工作期间初始化。

一般情况下,如果您想监控性能,可以使用:

  • 用于手动检查的Spark UI。
  • Spark REST API/applications/[app-id]/stages/[stage-id]特别有用)或TaskListener获取详细统计信息。

您还应该:

  • 执行多次运行并调整结果以更正初始化过程。
  • 如果需要,
  • unpersist个对象。
  • 避免可能的混淆因素(例如,同一应用程序执行的多个作业不是独立的,可能会受到缓存驱逐或GC等多种因素的影响。)