微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

python – 如何在调试模式下调用PySpark?

我使用Apache Spark 1.4设置了IntelliJ IDEA.

我希望能够将调试点添加到我的Spark Python脚本中,以便我可以轻松地调试它们.

我目前正在运行这一点Python来初始化spark过程

proc = subprocess.Popen([SPARK_SUBMIT_PATH, scriptFile, inputFile], shell=SHELL_OUTPUT, stdout=subprocess.PIPE)

if VERBOSE:
    print proc.stdout.read()
    print proc.stderr.read()

当spark-submit最终调用myFirstSparkScript.py时,调试模式未被启用并且正常执行.遗憾的是,编辑Apache Spark源代码并运行自定义副本是不可接受的解决方案.

有谁知道是否有可能在调试模式下使用spark-submit调用Apache Spark脚本?如果是这样,怎么样?

解决方法:

据我了解你的意图,你想要的东西在Spark架构下是不可能直接实现的.即使没有子进程调用,程序中唯一可以直接在驱动程序上访问的部分也是SparkContext.从其他部分开始,您可以通过不同的通信层实现隔离,包括至少一个(在本地模式下)JVM实例.为了说明我们使用PySpark Internals documentation的图表.

enter image description here

左侧框中的部分是可在本地访问的部分,可用于附加调试器.由于它最受限于JVM调用,因此除非您实际修改PySpark本身,否则实际上没有任何内容可供您使用.

右边的内容是远程发生的,从用户的角度来看,你使用的集群管理器几乎就是一个黑盒子.此外,在很多情况下,右边的Python代码只是调用JVM API.

这是不好的部分.好的部分是大多数时候不需要远程调试.排除可以轻松模拟的访问对象(如TaskContext),代码的每个部分都应该可以在本地轻松运行/测试,而无需使用Spark实例.

传递给操作/转换的函数采用标准和可预测的Python对象,并且还希望返回标准Python对象.同样重要的是这些副作用应该是免费的

因此,在一天结束时,您需要部分程序 – 一个可以交互式访问的薄层,并且仅基于输入/输出和“计算核心”进行测试,这不需要Spark进行测试/调试.

其他选择

那就是说你在这里没有完全没有选择.

本地模式

(被动地将调试器连接到正在运行的解释器)

普通的GDB和PySpark调试器都可以附加到正在运行的进程中.一旦启动了PySpark守护程序和/或工作进程,就可以执行此操作.在本地模式下,您可以通过执行虚拟操作来强制它,例如:

sc.parallelize([], n).count()

其中n是本地模式中可用的“核心”数(local [n]).在类Unix系统上逐步执行示例过程:

>启动PySpark shell:

$SPARK_HOME/bin/pyspark 

>使用pgrep检查没有运行守护进程:

➜  spark-2.1.0-bin-hadoop2.7$pgrep -f pyspark.daemon
➜  spark-2.1.0-bin-hadoop2.7$

>同样的事情可以在PyCharm中通过以下方式确定:

alt shift a并选择Attach to Local Process:

enter image description here

或运行 – >附加到本地进程.

此时你应该只看到PySpark shell(可能还有一些不相关的进程).

enter image description here


>执行虚拟动作:

sc.parallelize([],1).count()
>现在你应该看到守护进程和worker(这里只有一个):

➜  spark-2.1.0-bin-hadoop2.7$pgrep -f pyspark.daemon
13990
14046
➜  spark-2.1.0-bin-hadoop2.7$

enter image description here

具有较低pid的进程是守护进程,具有较高pid的进程是(可能)短暂的工作者.
>此时,您可以将调试器附加到感兴趣的进程:

>在PyCharm中选择要连接的过程.
>通过调用普通GDB:

gdb python <pid of running process>

这种方法的最大缺点是你在适当的时候找到了正确的翻译.

分布式模式

(使用连接到调试器服务器的活动组件)

与PyCharm

PyCharm提供Python Debug Server,可与PySpark作业一起使用.

首先,您应该为远程调试器添加配置:

> alt shift a并选择Edit Configurations或Run – >编辑配置.
>单击添加新配置(绿色加号),然后选择Python远程调试.
>根据您自己的配置配置主机和端口(确保从远程计算机到达该端口)

enter image description here


>启动调试服务器:

换班F9

您应该看到调试器控制台:

enter image description here


>确保可以通过安装或分发egg文件在工作节点上访问pyddev.
> pydevd使用必须包含在您的代码中的活动组件:

import pydevd
pydevd.settrace(<host name>, port=<port number>)

棘手的部分是找到包含它的正确位置,除非你调试批处理操作(如传递给mapPartitions的函数),否则可能需要修补PySpark源本身,例如pyspark.daemon.worker或RDD方法,如RDD.mapPartitions.假设我们对调试工作者行为感兴趣.可能的补丁可能如下所示:

diff --git a/python/pyspark/daemon.py b/python/pyspark/daemon.py
index 7f06d4288c..6cff353795 100644
--- a/python/pyspark/daemon.py
+++ b/python/pyspark/daemon.py
@@ -44,6 +44,9 @@ def worker(sock):
     """
     Called by a worker process after the fork().
     """
+    import pydevd
+    pydevd.settrace('foobar', port=9999, stdoutToServer=True, stderrToServer=True)
+
     signal.signal(SIGHUP, SIG_DFL)
     signal.signal(SIGCHLD, SIG_DFL)
     signal.signal(SIGTERM, SIG_DFL)

如果您决定修补Spark源,请务必使用位于$SPARK_HOME / python / lib中的已修补源而非打包版本.
>执行PySpark代码.回到调试器控制台,玩得开心:

enter image description here

其他工具

有许多工具,包括python-manholepyrasite,可以通过一些努力与PySpark一起使用.

注意:

当然,您可以在本地模式下使用“远程”(活动)方法,并且在某种程度上使用分布式模式的“本地”方法(您可以连接到工作节点并按照与本地模式相同的步骤).

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐