如何解析RDD会导致RPC超时?

时间:2017-11-21 23:57:23

标签: scala apache-spark

我有一个非常大的RDD,我正在缓存(它仍然适合内存),但由于它是如此之大,我想尽快解除它。但是,当我调用unpersist时,它会导致RPC超时错误:

17/11/21 23:25:55 INFO BlockManager: Removing RDD 171
Exception in thread "main" org.apache.spark.rpc.RpcTimeoutException: Futures timed out after [120 seconds]. This timeout is controlled by spark.rpc.askTimeout
        at org.apache.spark.rpc.RpcTimeout.org$apache$spark$rpc$RpcTimeout$$createRpcTimeoutException(RpcTimeout.scala:47)
        at org.apache.spark.rpc.RpcTimeout$$anonfun$addMessageIfTimeout$1.applyOrElse(RpcTimeout.scala:62)
        at org.apache.spark.rpc.RpcTimeout$$anonfun$addMessageIfTimeout$1.applyOrElse(RpcTimeout.scala:58)
        at scala.runtime.AbstractPartialFunction.apply(AbstractPartialFunction.scala:36)
        at org.apache.spark.rpc.RpcTimeout.awaitResult(RpcTimeout.scala:76)
        at org.apache.spark.storage.BlockManagerMaster.removeRdd(BlockManagerMaster.scala:135)
        at org.apache.spark.SparkContext.unpersistRDD(SparkContext.scala:1793)
        at org.apache.spark.rdd.RDD.unpersist(RDD.scala:216)

17/11/21 23:27:55 WARN BlockManagerMaster: Failed to remove RDD 171 - Cannot receive any reply from null in 120 seconds. This timeout is controlled by spark.rpc.askTimeout
org.apache.spark.rpc.RpcTimeoutException: Cannot receive any reply from null in 120 seconds. This timeout is controlled by spark.rpc.askTimeout

触发此错误的代码如下所示:

val tranformation1 = firstTransformation(inputData).cache
log("Tranformation1 Count: " + transformation1.count)
val transformation2 = secondTransformation(transformation1).cache
transformation1.unpersist()

取消存在RDD应该是一个相对便宜的行动。如何解析RDD会导致RPC超时?

2 个答案:

答案 0 :(得分:1)

稍微更全面的答案,因为它很可能是您遇到的依赖于版本的问题 - 事情发生了变化:

来自 JIRA:

RDD 和 DataFrame .unpersist() 方法,以及 Broadcast .destroy() 方法,采用可选的“阻塞”参数。默认 'false' 在所有情况下除了 (Scala) RDDs 和它们的 GraphX 子类。

所有这些方法中的默认值现在 'false'(非阻塞)。

Pyspark 的 RDD 和 Broadcast 类现在也有一个可选的“阻塞”参数,使用 相同的行为。

答案 1 :(得分:0)

unpersist() 默认是阻塞调用,所以它会等待RDD的所有块被删除。因此,一旦从驱动程序执行取消持久化 RDD 的指令,它将要求所有执行器取消持久化。驱动程序会等待执行程序的响应,执行程序可能会由于网络问题等多种原因超时。

为了避免异常,您可以使 unpersist() 非阻塞,这样您就不会收到此异常。

val tranformation1 = firstTransformation(inputData).cache
log("Tranformation1 Count: " + transformation1.count)
val transformation2 = secondTransformation(transformation1).cache
transformation1.unpersist(false)

在使非持久化非阻塞时,RDD 只是被标记为已删除,它可能会在 GC 或 Spark 的后台线程非持久化期间被清除。