Spark 作业代码(源码)IDE 远程调试

我们在编写Spark Application或者是阅读源码的时候,我们很想知道代码的运行情况,比如参数设置的是否正确等等。用Logging方式来调试是一个可以选择的方式,但是,logging方式调试代码有很多的局限和不便。今天我就来介绍如何通过IDE来远程调试Spark的Application或者是Spark的源码。

本文以调试Spark Application为例进行说明,本文用到的IDE是IntelliJ IDEA。步骤如下:

设置调试相关参数

JAVA自身支持调试功能,我们仅仅需要在程序启动之前,在JVM里面设置以下参数:

因为 Spark 应用程序是分布式的,所有调试的时候有点麻烦。但是如果知道方法也是很容易的。这里分两种情况来说明:

调试 Driver 端相关代码

Spark应用程序都有一个 Driver,如果你是 yarn-client 模式,这个 Driver 一般在你启动程序的机器上运行。如果你想调试这块模块,我们需要在 Driver 相关参数里面设置调试参数如下:

这个配置可以放到  里面;也可以在启动作业的时候通过 –conf 设置,比如:

这时候我们就可以调试 Driver 相关的代码了。

调试 Executor 端相关代码

一个Spark应用程序一般会启动一个或多个 Executor ,我们应用程序相关的计算逻辑一般都是在这里完成的,所有如果你想调试这块的代码,需要在 Executor 启动的 JVM 加入相关的调试参数如下:

这个配置可以放到 里面;也可以在启动作业的时候通过 –conf 设置,比如:

可以看见,Executor 的调试代码和 Driver 很类似。

启动Spark Application

上面我们已经设置好了相关的调试参数,现在我们可以启动 Spark Application 应用程序了。如下:

如果你看到第九行的输出(Listening for transport dt_socket at address: 8888),那恭喜你了,启动了远程调试。而且Spark Application正在等待我们的IDE连接它。

在IntelliJ IDEA设置远程调试的IP和Port

如果你需要调试 Driver 相关代码,依次选择 Edit Configurations->点击左上角的+号->Remote,在弹出的页面里面将Host和Port两个选项设置为你Driver运行所在节点机器的IP和Port。

设置完后,设置好程序的断电,然后再点击IDE上面的 Debug 按钮(就是那个虫子按钮)。

这时候,程序会继续运行,而且在IDE里面会输出以下信息

而且程序会跳到你设置断点的地方,你可以在你IDE的Dubegger里面看到如下的信息:

调试 Executor 相关的代码和上面设置类似,这里就不介绍了。

问题

在调试 Executor 相关代码大家可能会遇到相关的问题。如下:

这个问题是 Spark 在同一台机器上启动多个 Executor, 导致端口被占用,出现的异常,这时候你只需要把 –num-executors 设置为1即可解决这个问题。

我们还有可能遇到下面的问题:

这是因为我们在调试出现的时候,整个程序运行流程就卡到那了。这时候 Driver 就无法接收到 Executor 发来的心跳信息了,从而产生这种异常。解决办法也很简单,只需要把下面两个参数加大即可:

spark.executor.heartbeatInterval 参数不能设的比 spark.network.timeout 大。

在看和转发

都是一种支持