停止正在运行的 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 <master url> <driver ID>
有效,但您需要确保在集群模式下部署驱动程序并使用驱动程序 ID 而不是应用程序 ID。
此外,spark 默认提供一个提交端点http://<spark master>:6066/v1/submissions
,您可以使用http://<spark master>:6066/v1/submissions/kill/<driver ID>
杀死您的驱动程序。
由于我无法从任何 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 应用程序的主要内容,如果未能解决你的问题,请参考以下文章
zeppein 停止后,Zeppelin 在 Yarn Cluster 模式下启动的 Spark (Yarn) 应用程序不会被杀死