加入RDD时的java.lang.StackOverflowError - 仅在集群上

时间:2016-06-14 19:25:27

标签: apache-spark

我遇到了一个只在我在群集上运行spark作业时才会发生的问题。 当我在本地模式下运行时,它不会发生。

关于如何解决这个问题的建议非常受欢迎,但也非常感谢有关如何处理/调试此问题的建议。

我遇到的问题是当我尝试加入rdds时,我得到了一个java.lang.StackOverflowError,显然是在对象序列化期间。 这里是一些堆栈跟踪(它很长但是重复一遍) -

Caused by: java.lang.StackOverflowError
    at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1427)
    at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1178)
    at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1548)
    at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1509)
    at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1432)
    at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1178)
    at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1548)
    at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1509)
    at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1432)
    at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1178)
    at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1548)
    at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1509)

问题只发生在我尝试加入两个rdds时。

rdd1.join(rdd2).count

如果相反,我会做

rdd1.count
rdd2.count

此错误不会重现。
(对我而言,这意味着问题与我加入两个RDD的事实有关,而不是如何构建RDD,因为它们似乎是单独成功处理的,但我可能是错的。)

RDD由简单案例类的元组组成

val rdd1: RDD[(Device, Option[Usage])] = ...
val rdd2: RDD[(Device, Seq(Problem)] = ...

案例类只有简单属性(String,Int,DateTime,Option [?])

case class Device(customerId: String, appId: String, deviceId: String, lastEngagement: Option[DateTime], firstSeen: Option[DateTime], lastEngagementUserClass: Option[String])
case class Usage(customerId: String, appId: String, deviceId: String, eventTimestamp: DateTime, appVersion: String, appVersionCode: Int, appSignature: Int, osVersion: String, lifecyclePhase: String, userClass: String)
case class Problem(customerId: String, appId: String, deviceId: String, eventTimestamp: DateTime, problemType: Int, problemSubType: Int, problemReasonId: String)

我正在使用Spark 1.6.1和scala 2.10.5。

有什么建议吗?

更新

我意识到这是一个广泛的问题。 不幸的是,重现并不容易,因为它必须在火花簇上运行(不能在本地模式下重现),而且,它似乎不能用小样本数据重现 - 至少,我还不能创建这样的样本数据。

我希望有类似问题的人能够帮助我。我想我的问题是 - 你有类似的问题吗?你是怎么最终解决的?你是如何处理问题进行故障排除的?

1 个答案:

答案 0 :(得分:0)

在我找到解决方案之后立即跟进 - 在此写下此内容以防其他人遇到同样的问题。

我的结论是序列化问题是

rdd1.join(rdd2).

我的结论是,因为当我打电话时问题没有重现

rdd1.count()
rdd2.count()

有效地强制每个rdd单独计算。

这个假设是错误的 - 调用count根本不需要序列化对象。它只需要计算每个分区,然后对结果求和。

当我打电话时

rdd1.collect()

这个问题确实重现了,我能够深入挖掘,最终找到我代码中的问题。