为什么SparkSession为一个动作执行两次?

时间:2016-08-12 18:47:59

标签: java apache-spark apache-spark-sql

最近升级到Spark 2.0,我在尝试从JSON字符串创建一个简单的数据集时看到了一些奇怪的行为。这是一个简单的测试用例:

if (x < 0)
   x = 1;
else if (x >= 0)
   x = 2;

输出:

 SparkSession spark = SparkSession.builder().appName("test").master("local[1]").getOrCreate();
 JavaSparkContext sc = new JavaSparkContext(spark.sparkContext());

 JavaRDD<String> rdd = sc.parallelize(Arrays.asList(
            "{\"name\":\"tom\",\"title\":\"engineer\",\"roles\":[\"designer\",\"developer\"]}",
            "{\"name\":\"jack\",\"title\":\"cto\",\"roles\":[\"designer\",\"manager\"]}"
         ));

 JavaRDD<String> mappedRdd = rdd.map(json -> {
     System.out.println("mapping json: " + json);
     return json;
 });

 Dataset<Row> data = spark.read().json(mappedRdd);
 data.show();

似乎&#34;地图&#34;功能正在执行两次,即使我只执行一个动作。我认为Spark会懒惰地构建一个执行计划,然后在需要时执行它,但这似乎是为了将数据读取为JSON并对其执行任何操作,计划必须至少执行两次。

在这个简单的情况下它并不重要,但是当地图功能长时间运行时,这就成了一个大问题。这是对的,还是我错过了什么?

1 个答案:

答案 0 :(得分:6)

这是因为您没有为> paths $vpath $vpath[[1]] + 4/5 vertices: [1] 1 5 3 4 $epath NULL $predecessors NULL $inbound_edges NULL 提供架构。因此,Spark必须急切地扫描数据集以推断输出模式。

由于DataFrameReader未缓存,因此将对其进行两次评估:

  • 一次用于架构推理
  • 一次致电mappedRdd

如果你想阻止你应该为读者提供架构(Scala语法):

data.show