Spark中的accumulator和collect()之间的性能差异是什么?

时间:2019-09-05 06:14:55

标签: apache-spark

累加器基本上是spark中的共享变量,将由执行程序更新,但只能由驱动程序读取。 Collect()的目的是将执行程序中的所有数据导入驱动程序。

因此,在这两种情况下,我最终只能在驱动程序中获取数据。那么,当我们使用累加器或collect()将较大的RDD转换为LIST时,性能有何不同?

使用累加器将数据帧转换为列表的代码

val queryOutput = spark.sql(query)
val acc = spark.sparkContext.collectionAccumulator[Map[String,Any]]("JsonCollector")
val jsonString = queryOutput.foreach(a=>acc.add(convertRowToJSON(a)))
acc.value.asScala.toList


def convertRowToJSON(row: Row): Map[String,Any] = {
    val m = row.getValuesMap(row.schema.fieldNames)
    println(m)
    JSONObject(m).obj
  }

使用collect()将数据框转换为列表的代码

val queryOutput = spark.sql(query)
queryOutput.toJSON.collectAsList()

1 个答案:

答案 0 :(得分:0)

  

将大型RDD转换为LIST

这不是一个好主意。 collect会将数据从所有执行程序移至驱动程序内存。如果内存不足,则会抛出内存不足(OOM)异常。如果您的数据适合放在单台计算机的内存中,则可能不需要火花。

Spark本机支持数字类型的累加器,程序员可以添加对新类型的支持。它们可用于实现计数器(如MapReduce中的计数器)或总和。累加器的OUT参数应该是可以自动读取(例如,Int,Long)或线程安全(例如,同步集合)的类型,因为它将从其他线程读取。

CollectionAccumulator .value返回List(ArrayList实现),并且如果大小大于驱动程序内存,它将抛出OOM。

相关问题