如何将COGROUP用于大型数据集

时间:2017-11-08 12:55:26

标签: scala apache-spark apache-spark-sql

我有两个rdd'sval tab_a: RDD[(String, String)]val tab_b: RDD[(String, String)]我正在使用cogroup来处理这些数据集:

val tab_c = tab_a.cogroup(tab_b).collect.toArray

val updated = tab_c.map { x =>
  {
 //somecode
  }
}

我正在为地图函数使用tab_c cogrouped值,它适用于小型数据集,但在巨大的数据集中,它会抛出Out Of Memory exception

我尝试将最终值转换为RDD但没有运气同样的错误

val newcos = spark.sparkContext.parallelize(tab_c)

1.如何将Cogroup用于大型数据集?

2.我们能否坚持共同的价值观?

代码

 val source_primary_key = source.map(rec => (rec.split(",")(0), rec))
source_primary_key.persist(StorageLevel.DISK_ONLY)

val destination_primary_key = destination.map(rec => (rec.split(",")(0), rec))
destination_primary_key.persist(StorageLevel.DISK_ONLY)

val cos = source_primary_key.cogroup(destination_primary_key).repartition(10).collect()

  var srcmis: Array[String] = new Array[String](0)
var destmis: Array[String] = new Array[String](0)

var extrainsrc: Array[String] = new Array[String](0)
var extraindest: Array[String] = new Array[String](0)

var srcs: String = Seq("")(0)
var destt: String = Seq("")(0)

val updated = cos.map { x =>
  {

    val key = x._1
    val value = x._2

    srcs = value._1.mkString(",")
    destt = value._2.mkString(",")

    if (srcs.equalsIgnoreCase(destt) == false && destt != "") {
      srcmis :+= srcs
      destmis :+= destt

    }

    if (srcs == "") {

      extraindest :+= destt.mkString("")
    }

    if (destt == "") {

      extrainsrc :+= srcs.mkString("")
    }

  }

}

代码已更新:

  val tab_c = tab_a.cogroup(tab_b).filter(x => x._2._1 =!= x => x._2._2)
 // tab_c = {1,Compactbuffer(1,john,US),Compactbuffer(1,john,UK)}
      {2,Compactbuffer(2,john,US),Compactbuffer(2,johnson,UK)}..

错误:

 ERROR LiveListenerBus: SparkListenerBus has already stopped! Dropping event SparkListenerTaskEnd(4,3,ResultTask,FetchFailed(null,0,-1,27,org.apache.spark.shuffle.MetadataFetchFailedException: Missing an output location for shuffle 0
at org.apache.spark.MapOutputTracker$$anonfun$org$apache$spark$MapOutputTracker$$convertMapStatuses$2.apply(MapOutputTracker.scala:697)
at org.apache.spark.MapOutputTracker$$anonfun$org$apache$spark$MapOutputTracker$$convertMapStatuses$2.apply(MapOutputTracker.scala:693)


ERROR YarnScheduler: Lost executor 8 on datanode1: Container killed by YARN for exceeding memory limits. 1.0 GB of 1020 MB physical memory used. Consider boosting spark.yarn.executor.memoryOverhead.

谢谢

2 个答案:

答案 0 :(得分:1)

TL; DR Don&#t; t collect

为了安全地运行此代码,无需额外的假设(工作节点的平均要求可能会明显减少),每个节点(驱动程序和每个执行程序)都需要内存大大超过所有数据的总内存需求。

如果你在Spark之外运行它,你只需要一个节点。因此Spark在这里没有任何好处。

但是,如果您跳过collect.toArray并对数据分发做出一些假设,那么您可以正常运行它。

答案 1 :(得分:1)

当你使用collect()时,你基本上会告诉spark将所有结果数据移回主节点,这很容易产生瓶颈。此时您不再使用Spark,只是一台机器中的普通数组。

要触发计算,只需使用需要每个节点上的数据的内容,这就是执行程序位于分布式文件系统之上的原因。例如saveAsTextFile()

Here are some basic examples.

请记住,此处的整个目标(即,如果您有大数据)是将代码移动到您的数据并在那里进行计算,而不是将所有数据带到计算中。