Scala 取消持久化RDD如何导致RPC超时?
我有一个非常大的RDD,我正在缓存它(它仍然适合内存),但因为它太大了,我想尽快取消它的持久性。但是,当我对其调用unpersist时,它会导致RPC超时错误:Scala 取消持久化RDD如何导致RPC超时?,scala,apache-spark,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 ti
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超时?默认情况下,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的后台线程取消持久化过程中可能会被清除。稍微更全面一些,因为这很可能是您遇到的版本相关问题-情况已发生变化:
- 看到了吗?
- 默认情况下,Make.unpersist(),.destroy()始终是非阻塞的
同样的行为。多大是“非常大”?使用哪种缓存策略?@Ashalynd没什么疯狂的。16GB。该集群是一个10节点集群,每片容量为12GB。从总体上看,它并没有那么大,但它是目前为止我缓存的最大的RDD。你确定它真的适合内存吗?否则,它可能会在每次尝试访问RDD时动态地重新编译该RDD,即使对于unpersist也是如此。要检查这一点,您可以尝试减小数据的大小,并查看这种行为在哪一点起作用。@Ashalynd Yes。当我删除
unpersist()
时,RPC超时消失,并在Spark的存储选项卡中显示108%缓存UI@B.Smith你明白了吗?