Spark RDD.isEmpty需要花费很多时间

时间:2015-07-31 03:15:15

标签: apache-spark

我构建了一个Spark cluster
工人:2
芯:12
内存:总计32.0 GB,使用20.0 GB
每个工作人员获得1个CPU,6个核心和10.0 GB内存

我的程序从MongoDB cluster获取数据源。 SparkMongoDB cluster位于同一LAN(1000Mbps)。 MongoDB document格式: {name:string, value:double, time:ISODate}

大约有1300万份文件。

我希望从包含60个文档的特殊小时获取特殊name的平均值。 这是我的关键功能

 /*
  *rdd=sc.newAPIHadoopRDD(configOriginal, classOf[com.mongodb.hadoop.MongoInputFormat], classOf[Object], classOf[BSONObject])
   Apache-Spark-1.3.1 scala doc: SparkContext.newAPIHadoopFile[K, V, F <: InputFormat[K, V]](path: String, fClass: Class[F], kClass: Class[K], vClass: Class[V], conf: Configuration = hadoopConfiguration): RDD[(K, V)]
  */
def findValueByNameAndRange(rdd:RDD[(Object,BSONObject)],name:String,time:Date): RDD[BasicBSONObject]={

val nameRdd = rdd.map(arg=>arg._2).filter(_.get("name").equals(name))
val timeRangeRdd1 = nameRdd.map(tuple=>(tuple, tuple.get("time").asInstanceOf[Date]))
val timeRangeRdd2 = timeRangeRdd1.map(tuple=>(tuple._1,duringTime(tuple._2,time,getHourAgo(time,1))))
val timeRangeRdd3 = timeRangeRdd2.filter(_._2).map(_._1)
val timeRangeRdd4 = timeRangeRdd3.map(x => (x.get("name").toString, x.get("value").toString.toDouble)).reduceByKey(_ + _)

if(timeRangeRdd4.isEmpty()){
  return basicBSONRDD(name, time)
}
else{
 return timeRangeRdd4.map(tuple => {
  val bson = new BasicBSONObject()
  bson.put("name", tuple._1)
  bson.put("value", tuple._2/60)
  bson.put("time", time)
   bson })
  }
} 

以下是Job信息的一部分 enter image description here enter image description here

我的程序工作得很慢。这是因为isEmptyreduceByKey吗?如果是,我该如何改进呢?如果没有,为什么?
=======更新===

 timeRangeRdd3.map(x => (x.get("name").toString, x.get("value").toString.toDouble)).reduceByKey(_ + _)

是34

enter image description here

我知道 reduceByKey 是一项全局操作,可能需要花费很多时间,但是,它的成本超出了我的预算。我怎样才能改进它,或者它是Spark的缺陷。使用相同的计算和硬件,如果我使用多个java线程,它只需几秒钟。

1 个答案:

答案 0 :(得分:4)

首先,isEmpty仅仅是RDD阶段结束的时刻。 mapfilter不需要shuffle,UI中使用的方法始终是触发阶段更改/随机播放的方法...在这种情况下{{1 }}。为什么它的运行缓慢并不容易从这个角度看出来,尤其是在没有看到原始isEmpty的构成的情况下。我可以告诉您RDD首先检查isEmpty大小,然后执行partition并验证是否返回了数据。因此,可能性是网络中存在瓶颈或沿途阻塞的其他东西。它甚至可能是GC问题...点击take(1),看看还有什么可以从那里辨别出来。