为什么SPARK在持续运行后重复转换?

时间:2018-03-14 04:39:49

标签: scala apache-spark directed-acyclic-graphs persist

我有下一个代码。我正在计算执行持久操作并修复上面的转换。但是我注意到DAG和2个不同计数作业的阶段首先持续两次(当我希望在第二次计数调用中调用第二个持久化方法时)

val df = sparkSession.read
      .parquet(bigData)
      .filter(row => dateRange(row.getLong(5), lowerTimeBound, upperTimeBound))
      .as[SafegraphRawData]
      // So repartition here to be able perform shuffle operations later
      // another transformations and minor filtration
      .repartition(nrInputPartitions)
      // Firstly persist here since objects not fit in memory (Persist 67)
      .persist(StorageLevel.MEMORY_AND_DISK)

    LOG.info(s"First count  = " + df.count)

    val filter: BaseFilter = new BaseFilter()

    LOG.info(s"Number of partitions: " + df.rdd.getNumPartitions)
    val rddPoints= df
      .map(parse)
      .filter(filter.IsValid(_, deviceStageMetricService, providerdevicelist, sparkSession))
      .map(convert)
    // Since we will perform count and partitionBy actions, compute all above transformations/ Second persist 
    val dsPoints = rddPoints.persist(StorageLevel.MEMORY_AND_DISK)
    val totalPoints = dsPoints.count()
    LOG.info(s"Second count  = $totalPoints")

First count LOG.info(s"First count  = " + df.count)

LOG.info(s"Second count  = $totalPoints")

3 个答案:

答案 0 :(得分:2)

当你说StorageLevel.MEMORY_AND_DISK spark尝试将所有数据放入内存中时,如果它不适合它会溢出到磁盘。

现在你在这里做多次坚持。在spark中,内存缓存是LRU,因此后面的持久存储将覆盖以前的缓存数据。

即使您指定StorageLevel.MEMORY_AND_DISK当数据被缓存内存中的另一个缓存数据驱逐出来时,火花也不会将其溢出到磁盘。因此,当您执行下一次计数时,它需要重新评估DAG,以便它可以检索缓存中不存在的分区。

我建议你使用StorageLevel.DISK_ONLY来避免这种重新计算。

答案 1 :(得分:0)

这是整个场景。

persist和cache也是Spark的转型。在应用任何一个所述转换之后,应该使用任何动作来将RDD或DF缓存到存储器中。

其次,缓存或持久的单位是“分区”。当执行缓存或持久化时,它将仅保存可以在内存中保留的那些分区。一旦遇到任何新动作,将无法保存在整个存储器整个DAG中的剩余分区。

答案 2 :(得分:0)

试试

val df = sparkSession.read
      .parquet(bigData)
      .filter(row => dateRange(row.getLong(5), lowerTimeBound, upperTimeBound))
      .as[SafegraphRawData]
      // So repartition here to be able perform shuffle operations later
      // another transformations and minor filtration
      .repartition(nrInputPartitions)
      // Firstly persist here since objects not fit in memory (Persist 67)

df.persist(StorageLevel.MEMORY_AND_DISK)