【问题标题】:How to debug Spark application locally?如何在本地调试 Spark 应用程序?
【发布时间】:2020-01-01 22:18:20
【问题描述】:

我想一步步学习 Spark,想知道如何在本地调试 Spark 应用程序?谁能详细说明执行此操作所需的步骤?

我可以通过命令行在本地运行 spark 网站上的 simpleApp,但我只需要单步执行代码,看看它是如何工作的。

【问题讨论】:

  • 我真的不知道你所说的“学习调试”是什么意思。你可以看看这篇教程如何在 IntelliJ ide docs.sigmoidanalytics.com/index.php/… 本地设置 spark。
  • 我的意思是“如何在 spark 网站上单步执行 SimpleApp 应用程序。有 SimpleApp.java 文件和 pom.xml(如 spark 网站上的编码)。我该如何使用Intellij IDE 逐行通过 SimpleApp.java 中的代码并查看每一行的实际作用?我希望能够在不将作业发送到集群的情况下做到这一点。我只想在笔记本电脑上逐步完成代码,本地。您提供的链接提供了使用 IntelliJ IDEA 构建 Spark 应用程序的步骤。如何逐行执行代码?非常感谢任何帮助。谢谢。
  • 我不知道 scala 但至少在 java 中你可以使用标准的 IDEA 调试器(在本地模式下)。如果您有大量收藏,您必须记住一件事,您必须逐步了解所有元素。

标签: apache-spark


【解决方案1】:

这是我使用 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 源,您应该能够很好地单步执行代码。

【讨论】:

  • 完整的命令行在agentlib 之前错过了-。由于字符更改不足,我无法编辑。
【解决方案2】:

启动 Spark shell。这是直接来自Spark documentation

./bin/spark-shell --master local[2]

您还将看到称为REPL 的Spark shell。这是迄今为止学习 Spark 的最佳方式。我将 80% 的时间花在 Spark shell 中,另外 20% 的时间用于将代码翻译到我的应用程序中。

【讨论】:

  • 如果应用程序是用 Java 编写的呢?
  • Scala spark-shell 可以加载 Java jars,然后您可以从 Scala 运行您的应用程序和/或方法。
  • 如果您正在构建一个(更大的)函数,并且您一直在更改,并且您需要在 shell 中对其进行测试,那么这不是很有用。每次改进后都需要重新导入该功能。但这需要停止和启动 shell(每次!),这不是构建代码的快速方法。 OP 要求(python)类似 ipdb 的功能(显然只在本地模式下有用),这显然不存在。
  • 不一定。您可以在脚本中定义函数,然后将其导入 shell。 Shell 将允许您一遍又一遍地导入相同的函数或集合或函数/类/对象等。像魅力一样工作。
【解决方案3】:

只需传递 java 选项即可打开调试端口。这是解决您问题的好文章 - http://danosipov.com/?p=779 我正在使用它像

$ SPARK_JAVA_OPTS=-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005 spark-shell

(是的,SPARK_JAVA_OPTS 已被弃用,但它可以正常工作)

【讨论】:

  • 我也偶然发现了你提到的文章,但是 SPARK_JAVA_OPTS 在这种形式下对我不起作用。我不得不修改它,它为我做了什么:export SPARK_JAVA_OPTS=-agentlib:jdwp=transport=dt_socket,server=y,address=5005,suspend=y,onuncaught=n
【解决方案4】:

@Jason Evans 的回答对我不起作用。但是

--conf spark.driver.extraJavaOptions=-Xrunjdwp:transport=dt_socket,server=y,address=8086,suspend=n

工作

【讨论】:

  • 是的,@ryan 指出的“agentlib”之前缺少一个“-”,现在已修复
【解决方案5】:

@Jason Evan 的回答只需要一个小改动。它在字符串“agentlib....”之前需要一个'-'

 --conf spark.driver.extraJavaOptions=-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=5005

你也可以使用选项“--driver-java-options”来达到同样的目的

--driver-java-options -agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=5005

【讨论】:

  • 是的,@ryan 关于缺少的“-”是正确的,谢谢!
【解决方案6】:

你可以在spark-env.sh试试这个:

SPARK_SUBMIT_OPTS=-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=8888

【讨论】:

    【解决方案7】:

    先选择一个版本的spark,然后再选择一个IDE,intellij会更好。查看此 spark 版本的源代码并确保您可以从 IDE 成功构建它(更多 here)。一旦你有一个干净的构建,搜索测试用例或测试套件。例如“SubquerySuite”是一个简单的然后像一个普通的应用程序调试它。评论您需要帮助的任何具体步骤

    【讨论】:

      【解决方案8】:

      这是在控制台上获取所有内容的方法:

      首先在此处查看您希望 spark (log4j) 在控制台上打印的信息级别:

      https://jaceklaskowski.gitbooks.io/mastering-apache-spark/spark-logging.html

      然后提交你的命令如下:

      path/to/spark-submit
        --master local[a number of cores here from your CPU]
        --driver-java-options "-Dlog4j.configuration=file:/path/to/log4j-driver.properties 
        -Dvm.logging.level=ALL"
      

      “ALL”将为您提供您可以获得的所有信息。同样,如果 spark 找不到您的 log4.properties 文件也没关系,它应该加载您所需的日志记录级别的设置,并且信息将打印在您的屏幕上。

      【讨论】:

        最近更新 更多