Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/apache-spark/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala 在UDF中使用时,火花蓄能器为空_Scala_Apache Spark - Fatal编程技术网

Scala 在UDF中使用时,火花蓄能器为空

Scala 在UDF中使用时,火花蓄能器为空,scala,apache-spark,Scala,Apache Spark,我正在努力优化我的Spark流程,并尝试使用带有蓄能器的UDF。我已经让累加器自己工作了,我想看看使用UDF是否能加快速度。但是,当我在UDF中包装累加器时,它仍然是空的。我是不是特别出了什么问题?即使使用我的.count它仍然没有执行,延迟执行是否会发生什么情况 输入: 0,[0.11,0.22] 1,[0.22,0.33] 输出: (0,0,0.11),(0,1,0.22),(1,0,0.22),(1,1,0.33) 代码 看起来这里唯一的问题是使用count来“触发”延迟评估的UDF:

我正在努力优化我的Spark流程,并尝试使用带有蓄能器的UDF。我已经让累加器自己工作了,我想看看使用UDF是否能加快速度。但是,当我在UDF中包装累加器时,它仍然是空的。我是不是特别出了什么问题?即使使用我的
.count
它仍然没有执行,延迟执行是否会发生什么情况

输入:

0,[0.11,0.22]
1,[0.22,0.33]
输出:

(0,0,0.11),(0,1,0.22),(1,0,0.22),(1,1,0.33)
代码


看起来这里唯一的问题是使用
count
来“触发”延迟评估的UDF:Spark“聪明”到足以意识到
select
操作不能更改
count
的结果,因此不能真正执行UDF。选择不同的操作(例如,
收集
)表明UDF工作并更新累加器

下面是一个(更简洁)的示例:


成功了。但是收集感觉很有侵略性。我使用累加器来避免使用collect。我是不是有点偏执?哦,不,你绝对不应该在实际数据集的任何生产代码中使用collect;我只是用它来证明自己的行为;是否没有对数据帧执行其他操作?如果是这样的话,恐怕使用累加器有点滥用——它是用来产生副作用的(并且不如使用数据帧转换那么健壮和有弹性)。也许,如果问题是如何优化备选方案,我们需要查看您尝试过的备选方案的代码(
groupBy
,然后是
collectamap
?),那么这就是我在进入这个兔子洞之前试图解决的实际问题。
  val accum = new MapAccumulator2d()
  val session = SparkSession.builder().getOrCreate()
  session.sparkContext.register(accum)

  //Does not work - Empty Accumlator
  val rowAccum = udf((itemId: Int, item: mutable.WrappedArray[Float]) => {
    val map = item
      .zipWithIndex
      .map(ff => {
        ((itemId, ff._2), ff._1.toDouble)
      }).toMap
    accum.add(map)
    itemId
  })
  dataFrame.select(rowAccum(col("itemId"), col("jaccardList"))).count

  //Works
  dataFrame.foreach(f => {
    val map = f.getAs[mutable.WrappedArray[Float]](1)
      .zipWithIndex
      .map(ff => {
        ((f.getInt(0), ff._2), ff._1.toDouble)
      }).toMap
    accum.add(map)
  })

  val list = accum.value.toList.map(f => (f._1._1, f._1._2, f._2))
val accum = sc.longAccumulator

val rowAccum = udf((itemId: Int) => { accum.add(itemId); itemId })

val dataFrame = Seq(1,2,3,4,5).toDF("itemId")

dataFrame.select(rowAccum(col("itemId"))).count()   // won't trigger UDF
println(s"RESULT: ${accum.value}") // prints 0

dataFrame.select(rowAccum(col("itemId"))).collect() // triggers UDF 
println(s"RESULT: ${accum.value}") // prints 15