全部 我在mongodb有一张大约1TB的桌子。我尝试使用mongo连接器将它加载到spark中,但是在执行18分钟后我一直在堆栈溢出。
java.lang.StackOverflowError:
at scala.collection.TraversableLike$$anonfun$filter$1.apply(TraversableLike.scala:264)
at scala.collection.MapLike$MappedValues$$anonfun$foreach$3.apply(MapLike.scala:245)
at scala.collection.MapLike$MappedValues$$anonfun$foreach$3.apply(MapLike.scala:245)
at scala.collection.TraversableLike$WithFilter$$anonfun$foreach$1.apply(TraversableLike.scala:772)
....
at scala.collection.MapLike$MappedValues$$anonfun$foreach$3.apply(MapLike.scala:245)
at scala.collection.MapLike$MappedValues$$anonfun$foreach$3.apply(MapLike.scala:245)
at scala.collection.TraversableLike$WithFilter$$anonfun$foreach$1.apply(TraversableLike.scala:772)
16/06/29 08:42:22 INFO YarnAllocator: Driver requested a total number of 54692 executor(s).
16/06/29 08:42:22 INFO YarnAllocator: Will request 46501 executor containers, each with 4 cores and 5068 MB memory including 460 MB overhead
是因为我没有提供足够的内存吗?或者我应该提供更多存储? 我试图添加检查点,但它没有帮助。 我在代码中更改了一些值,因为它们与我的公司数据库有关,但整个代码仍然适用于这个问题。
val sqlContext = new SQLContext(sc)
val builder = MongodbConfigBuilder(Map(Host -> List("mymongodurl:mymongoport"), Database -> "mymongoddb", Collection ->"mymongocollection", SamplingRatio -> 0.01, WriteConcern -> "normal"))
val readConfig = builder.build()
val mongoRDD = sqlContext.fromMongoDB(readConfig)
mongoRDD.registerTempTable("mytable")
val dataFrame = sqlContext.sql("SELECT u_at, c_at FROM mytable")
val deltaCollect = dataFrame.filter("u_at is not null and c_at is not null and u_at != c_at").rdd
val mapDelta = deltaCollect.map {
case Row(u_at: Date, c_at: Date) =>{
if(u_at.getTime == c_at.getTime){
(0.toString, 0l)
}
else{
val delta = ( u_at.getTime - c_at.getTime ) / 1000/60/60/24
(delta.toString, 1l)
}
}
}
val reduceRet = mapDelta.reduceByKey(_+_)
val OUTPUT_PATH = s"./dump"
reduceRet.saveAsTextFile(OUTPUT_PATH)
答案 0 :(得分:3)
如您所知,Apache Spark在执行作业时执行内存处理,即将要处理的数据加载到内存中。根据您的问题和评论,您有一个大到1TB的数据集,Spark可用的内存大约为每个核心8GB。因此,在这种情况下,您的spark执行器将永远是内存不足的。
为避免这种情况,您可以按照以下两个选项之一进行操作:
Storage Level
更改为MEMORY_AND_DISK
。通过这种方式,Spark不会将完整数据加载到其内存中;相反,它会尝试将额外的数据泄漏到磁盘中。但是,由于内存和磁盘之间的事务处理,性能会降低。查看RDD persistence 答案 1 :(得分:1)
我添加了另一个java选项" -Xss32m"激发驱动程序为每个线程提高堆栈的内存,而这个异常不再抛出。我是多么愚蠢,我应该早点尝试过。但是显示了另一个问题,我将不得不检查更多。还是非常感谢你的帮助。