这是我使用 IntelliJ 的方法。
首先,确保您可以使用 spark-submit 在本地运行您的 spark 应用程序,例如类似:
spark-submit --class MyMainClass myapplication.jar
然后,通过添加如下选项,告诉您的本地 spark 驱动程序在调试器启动时暂停并等待来自调试器的连接:
--conf spark.driver.extraJavaOptions=-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=5005
其中agentlib:jdwp 是Java Debug Wire Protocol (JDWP) 选项,后跟以逗号分隔的子选项列表:
-
transport 定义了调试器和被调试对象之间使用的连接协议——无论是套接字还是“共享内存”——你几乎总是想要套接字 (dt_socket),除非我相信在某些情况下在 Microsoft Windows 上
-
server 在与调试器(或相反,客户端)对话时,这个进程是否应该是服务器——你总是需要一台服务器和一台客户端。在这种情况下,我们将成为服务器并等待来自调试器的连接
-
suspend 是否暂停执行直到调试器成功连接。我们将其打开,以便在调试器连接之前驱动程序不会启动
-
address 这里,这是要监听的端口(用于传入的调试器连接请求)。您可以将其设置为任何可用端口(您只需确保将调试器配置为连接到同一端口)
所以现在,您的spark-submit 命令行应该类似于:
spark-submit \
--name MyApp \
--class MyMainClass \
--conf spark.driver.extraJavaOptions=agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=5005
现在如果你运行上面的,你应该看到类似的东西
Listening for transport dt_socket at address: 5005
您的 Spark 应用程序正在等待调试器附加。
接下来,打开包含 Spark 应用程序的 IntelliJ 项目,然后打开“运行 -> 编辑配置...”,然后单击“+”添加新的运行/调试配置,并选择“远程”。给它一个名字,例如“SparkLocal”,为 Transport 选择“Socket”,为 Debugger 模式选择“Attach”,为 Host 输入“localhost”,为 Port 输入上面使用的端口,在本例中为“5005”。点击“确定”保存。
在我的 IntelliJ 版本中,它为您提供了用于调试进程的调试命令行建议,它使用“suspend=n”——我们忽略了这一点并使用“suspend=y”(如上)因为我们希望应用程序等到我们连接后再启动。
现在您应该可以进行调试了。只需使用上述命令启动 spark,然后选择您刚刚创建的 IntelliJ 运行配置并单击 Debug。 IntelliJ 应该连接到您的 Spark 应用程序,该应用程序现在应该开始运行。您可以设置断点、检查变量等。
火花壳
使用spark-shell 只需导出SPARK_SUBMIT_OPTS 如下:
export SPARK_SUBMIT_OPTS=-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005
使用您的调试器(例如 IntelliJ IDEA)附加到 localhost:5005 并导入 Spark 源,您应该能够很好地单步执行代码。