停止正在运行的 Spark 应用程序

Posted

技术标签:

【中文标题】停止正在运行的 Spark 应用程序【英文标题】:Stopping a Running Spark Application 【发布时间】:2015-05-07 06:56:32 【问题描述】:

我正在以独立模式运行 Spark 集群。

我已经使用选项在集群模式下提交了一个 Spark 应用程序:

--deploy-mode cluster –supervise 

这样作业是容错的。

现在我需要保持集群运行但停止应用程序运行。

我尝试过的事情:

停止集群并重新启动它。但申请恢复 当我这样做时执行。 使用了名为 DriverWrapper 的守护程序的 Kill -9,但此后该作业再次恢复。 我还删除了临时文件和目录并重新启动了集群,但作业又恢复了。

所以运行的应用程序确实是容错的。

问题: 基于上述情况,有人可以建议我如何阻止作业运行,或者我可以尝试如何阻止应用程序运行但保持集群运行。

如果我打电话给sparkContext.stop(),我应该会做一些事情,但这需要在代码中做一些工作,这没关系,但你能建议任何其他方式而不需要更改代码。

【问题讨论】:

Here's a solution 使用 Spark 独立集群的 Spark REST API。 【参考方案1】:

如果您希望杀死一个反复失败的应用程序,您可以通过以下方式执行此操作:

./bin/spark-class org.apache.spark.deploy.Client kill <master url> <driver ID>

您可以通过 http://:8080 的独立 Master Web UI 找到驱动程序 ID。

来自Spark Doc

【讨论】:

您是否知道是否有办法在没有驱动程序 ID 的情况下阻止它? id 每次都会改变。我想要一个运行 spark-submit 的 jenkins 作业,但在提交新进程之前终止前一个进程。 什么是主网址?端口是什么样的?使用 mesos 运行它不能识别 --master mesos://... 像其他命令一样。 spark-submit 似乎已经杀了。 我也有同样的问题。不幸的是,我没有运行集群,并且该集群在没有授予 UI 杀死权限的情况下运行。当我运行此命令时,我得到“Driver app-XXX 已经完成或不存在”(当我在浏览器 UI 上看到它时),我也尝试使用带有 --kill 选项的 spark-submit 并且没有运气。还有什么我可以尝试的吗? @nickn 看看我的回答,我遇到了同样的问题,过了一会儿就解决了——尽管是以不受支持的方式。 @user2662165 除非您以集群模式提交应用程序,否则使用 spark-class、spark-submit 或提交 API 端点杀死它的任何方法都不起作用。我也很难理解这一点。如果您需要终止在客户端模式下运行的驱动程序(默认),您必须使用操作系统命令手动终止该进程。【参考方案2】:

重新审视这一点,因为我无法在不调试一些东西的情况下使用现有答案。

我的目标是以编程方式杀死每天持续运行一次的驱动程序,将任何更新部署到代码,然后重新启动它。所以我不会提前知道我的驱动程序 ID 是什么。我花了一些时间才弄清楚,如果您使用 --deploy-mode cluster 选项提交驱动程序,您只能杀死驱动程序。我也花了一些时间才意识到应用程序 ID 和驱动程序 ID 之间存在差异,虽然您可以轻松地将应用程序名称与应用程序 ID 关联起来,但我还没有找到一种通过它们的 api 端点来判断驱动程序 ID 的方法并将其与应用程序名称或您正在运行的类相关联。因此,虽然run-class org.apache.spark.deploy.Client kill &lt;master url&gt; &lt;driver ID&gt; 有效,但您需要确保在集群模式下部署驱动程序并使用驱动程序 ID 而不是应用程序 ID。

此外,spark 默认提供一个提交端点http://&lt;spark master&gt;:6066/v1/submissions,您可以使用http://&lt;spark master&gt;:6066/v1/submissions/kill/&lt;driver ID&gt; 杀死您的驱动程序。

由于我无法从任何 api 端点找到与特定作业相关的驱动程序 ID,我编写了一个 python 网络爬虫从端口 8080 的基本 spark 主网页获取信息,然后使用端点位于端口 6066。我希望以受支持的方式获取此数据,但这是我能找到的最佳解决方案。

#!/usr/bin/python

import sys, re, requests, json
from selenium import webdriver

classes_to_kill = sys.argv
spark_master = 'masterurl'

driver = webdriver.PhantomJS()
driver.get("http://" + spark_master + ":8080/")

for running_driver in driver.find_elements_by_xpath("//*/div/h4[contains(text(), 'Running Drivers')]"):
    for driver_id in running_driver.find_elements_by_xpath("..//table/tbody/tr/td[contains(text(), 'driver-')]"):
        for class_to_kill in classes_to_kill:
            right_class = driver_id.find_elements_by_xpath("../td[text()='" + class_to_kill + "']")
            if len(right_class) > 0:
                driver_to_kill = re.search('^driver-\S+', driver_id.text).group(0)
                print "Killing " + driver_to_kill
                result = requests.post("http://" + spark_master + ":6066/v1/submissions/kill/" + driver_to_kill)
                print json.dumps(json.loads(result.text), indent=4)

driver.quit()

【讨论】:

这些天我使用 DC/OS 和 mesos 来运行 spark 作业,mesos 提供了一个端点来获取所有正在运行的 mesos 框架。从那里您可以轻松获取 spark 作业名称和驱动程序 ID。 mesos 端点是/state-summary,它返回类似"frameworks":["name":"...","id":"..."] 的json。该 ID 不仅包含驱动程序 ID,还包含“驱动程序-”,之后的所有内容都是您的驱动程序 ID。 post 方法适用于基于 mesos 的部署,谢谢。【参考方案3】:

https://community.cloudera.com/t5/Support-Questions/What-is-the-correct-way-to-start-stop-spark-streaming-jobs/td-p/30183

如果您的主人使用 yarn

,请根据此链接使用停止
yarn application -list

yarn application -kill application_id

【讨论】:

以上是关于停止正在运行的 Spark 应用程序的主要内容,如果未能解决你的问题,请参考以下文章

如何优雅地终止正在运行的Spark Streaming程序

从 s3 读取文件时 Spark 应用程序停止

zeppein 停止后,Zeppelin 在 Yarn Cluster 模式下启动的 Spark (Yarn) 应用程序不会被杀死

Spark集群上运行jar程序,状态一直Accepted且不停止不报错

如何在CDH 5上运行Spark应用程序

如何在CDH 5上运行Spark应用程序