Spark驱动程序的RMI库导致Full GC暂停(System.gc())

时间:2017-08-09 18:12:36

标签: java apache-spark garbage-collection jvm garbage

我们的Spark执行程序日志包含以下内容:

org.apache.spark.rpc.RpcTimeoutException: Futures timed out after [10 seconds]. This timeout is controlled by spark.executor.heartbeatInterval

确定这些是从执行程序到驱动程序的心跳,我怀疑驱动程序上的GC issus,从而启用了GC日志记录,并找到了这些:

[Full GC (System.gc()) 5402.271: [CMS: 10188280K->8448710K(14849412K),27.2815605 secs] 10780958K->8448710K(15462852K), [Metaspace: 93432K->93432K(96256K)], 27.2833999 secs] [Times: user=27.28 sys=0.01, real=27.29 secs]

显然,有些事情会调用System.gc(),导致驱动程序上的GC长时间停顿(27秒)。进一步看,RMI是一个嫌疑人,因为这些System.gc()电话每30分钟发生一次。 我在Spark驱动程序上找不到RMI的这个问题。我应该通过设置System.gc()来启用-XX:+DisableExplicitGC来电吗?

1 个答案:

答案 0 :(得分:1)

很有趣我只是在研究类似的问题。我可以看到Spark中的一些代码实际上调用了System.gc()

可能值得在Spark中开辟一个JIRA来讨论这个问题。

我理解使用System.gc()拨打电话并非最佳做法,主要是因为它会停止所有其他对性能产生重大影响的线程。但是,我可以在Java Oracle文档中看到,从Java 1.6开始引入了一个额外的JVM参数,以便同时运行System.gc()(-XX:+ ExplicitGCInvokesConcurrent):

http://docs.oracle.com/javase/6/docs/technotes/guides/vm/cms-6.html

您可以尝试将其设置为附加参数:

spark.executor.extraJavaOptions =" -XX:+ ExplicitGCInvokesConcurrent"

根据您设置参数的方式,您可以将其放在Spark的配置文件中,或者使用spark命令中的--conf line参数传递它(spark-submit,spark-贝壳等......)。

更新

在Spark 2.x的ContextCleaner.scala文件中找到以下注释:

/**
* How often to trigger a garbage collection in this JVM.
*
* This context cleaner triggers cleanups only when weak references are  garbage collected.
* In long-running applications with large driver JVMs, where there is little memory pressure
* on the driver, this may happen very occasionally or not at all. Not  cleaning at all may
* lead to executors running out of disk space after a while.
*/