spark:广播被销毁后尝试使用

时间:2018-06-20 01:27:32

标签: scala apache-spark

以下代码有效

 @throws(classOf[IKodaMLException])
 def soMergeTarget1( oldTargetIdx: Double, newTargetIdx: Double): RDDLabeledPoint =
 {
   try
   {
    logger.trace("\n\n--sparseOperationRenameTargetsInNumeriOrder--\n\n")
    val oldTargetIdxb=spark.sparkContext.broadcast(oldTargetIdx)
    val newTargetIdxb=spark.sparkContext.broadcast(newTargetIdx)

    val newdata:RDD[(LabeledPoint,Int,String)] = sparseData.map
    {
      r =>

        val currentLabel: Double = r._1.label
        currentLabel match
        {
          case x if x == oldTargetIdxb.value =>
          val newtrgt=newTargetIdxb.value
          (new LabeledPoint(newtrgt, r._1.features), r._2, r._3)
          case _ => r
        }
    }
  val newtargetmap=ilp.targetMap.filter(e=> !(e._2 == oldTargetIdx))
  oldTargetIdxb.destroy
  newTargetIdxb.destroy
  new RDDLabeledPoint(newdata,copyColumnMap,newtargetmap,ilp.name)
}

但是,在方法末尾销毁了广播变量之后,RDD中的newtrgt变量也被销毁了。 问题在于,一旦从此方法返回RDD,任何分析人员都可以在任何代码中使用它。因此,我似乎已经失去了对广播变量的所有控制。

问题:

如果我不销毁这些变量,当对RDD的引用消失时会火花销毁它们吗?

(也许是一个幼稚的问题,但是...。)我尝试了一点技巧val newtrgt=oldTargetIdxb.value + 1 -1,认为这可能会创建一个不同于广播变量的新引用。没用我必须承认这让我感到惊讶。有人可以解释为什么这种黑客攻击无效吗(我并不是说这是个好主意,但我很好奇)。

1 个答案:

答案 0 :(得分:1)

我找到了答案here

不是我的答案 ,但是值得在SO上共享...以及为什么我在Spark文档中看不到这一点。重要:

塞恩·欧文:

  

您要主动取消播放(或持续播放)   不再需要的变量。他们最终可能是   当驱动程序上的引用被垃圾回收时删除,但是   您通常不想依赖它。

后续问题:

  

感谢您的回复。唯一的问题是积极管理   广播变量要求将广播变量返回到   调用方,如果创建广播变量的函数没有   包含任何动作。那就是使用广播的范围   变量在许多情况下不能破坏广播变量。对于   例如:

==============

def perfromTransformation(rdd: RDD[int]) = {
   val sharedMap = sc.broadcast(map)
   rdd.map{id => 
      val localMap = sharedMap.vlaue
      (id, localMap(id))
   }
}

def main = {
    ....
    performTransformation(rdd).toDF("id", "i").write.parquet("dummy_example")
}

==============

  

在上面的示例中,我们无法在   之所以执行write.parquet是因为RDD的计算是延迟的。我们将获得   例外

塞恩·欧文:

  

是的,尽管持久和毁灭之间存在差异,   无论哪种方式,您都会遇到相同类型的问题。您确实必须   关于何时不再需要广播变量的原因   面对懒惰的评估,这很难。

     

有时候这很明显,您可以利用它来   主动释放资源。您可能需要考虑重组   计算以释放更多资源(如果是)   规模很重要。

     

请记住,计算和缓存的内容可能会丢失并且   即使已经确定其父RDD,也要重新计算   计算,似乎不需要。这就是为什么不持久经常出现   更好的调用是因为它允许变量为   在这种情况下,请重新播放。销毁后永久关闭   广播。