累加器基本上是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()
答案 0 :(得分:0)
将大型RDD转换为LIST
这不是一个好主意。 collect会将数据从所有执行程序移至驱动程序内存。如果内存不足,则会抛出内存不足(OOM)异常。如果您的数据适合放在单台计算机的内存中,则可能不需要火花。
Spark本机支持数字类型的累加器,程序员可以添加对新类型的支持。它们可用于实现计数器(如MapReduce中的计数器)或总和。累加器的OUT参数应该是可以自动读取(例如,Int,Long)或线程安全(例如,同步集合)的类型,因为它将从其他线程读取。
CollectionAccumulator .value
返回List(ArrayList实现),并且如果大小大于驱动程序内存,它将抛出OOM。