我有一个连续运行的Spark Streaming作业。我如何优雅地停止工作?我已经阅读了在作业监视中附加关闭钩子并将SIGTERM发送到作业的通常建议。
sys.ShutdownHookThread {
logger.info("Gracefully stopping Application...")
ssc.stop(stopSparkContext = true, stopGracefully = true)
logger.info("Application stopped gracefully")
}
它似乎有效,但看起来不是最简单的停止工作方式。我在这里错过了什么吗?
从代码的角度来看,它可能有意义,但您如何在群集环境中使用它?如果我们启动一个火花流工作(我们在集群中的所有节点上分配作业),我们将不得不跟踪作业的PID和运行它的节点。最后,当我们必须停止进程时,我们需要跟踪作业运行的节点以及该进程的PID。我只是希望流媒体作业有一种更简单的工作控制方式。
答案 0 :(得分:20)
您可以通过运行以下命令在群集模式下停止流式上下文,而无需发送SIGTERM。这将停止流式上下文,而无需使用线程挂钩显式停止它。
spark.streaming.stopGracefullyOnShutdown=true
- $ MASTER_REST_URL是火花驱动程序的其余URL,例如spark:// localhost:6066
- $ DRIVER_ID类似于driver-20150915145601-0000
如果您希望spark能够优雅地停止您的应用,您可以在最初提交spark应用时尝试设置以下系统属性(请参阅http://spark.apache.org/docs/latest/submitting-applications.html设置spark配置属性)。
{{1}}
这没有正式记录,我从查看1.4源代码中收集了这些内容。此标志在独立模式下受到尊重。我还没有在集群模式下测试它。
我正在使用spark 1.4。*
答案 1 :(得分:2)
取决于用例以及如何使用驱动程序。
考虑您要从Spark结构化流中收集一些N条记录(推文),将它们存储在Postgresql中并在计数超过N条记录时停止流的情况。
一种方法是使用累加器和python线程。
共享代码段以用于理解/说明目的...
import threading
import time
def check_n_stop_streaming(query, acc, num_records=3500):
while (True):
if acc.value > num_records:
print_info(f"Number of records received so far {acc.value}")
query.stop()
break
else:
print_info(f"Number of records received so far {acc.value}")
time.sleep(1)
...
count_acc = spark.sparkContext.accumulator(0)
...
def postgresql_all_tweets_data_dump(df,
epoch_id,
raw_tweet_table_name,
count_acc):
print_info("Raw Tweets...")
df.select(["text"]).show(50, False)
count_acc += df.count()
mode = "append"
url = "jdbc:postgresql://{}:{}/{}".format(self._postgresql_host,
self._postgresql_port,
self._postgresql_database)
properties = {"user": self._postgresql_user,
"password": self._postgresql_password,
"driver": "org.postgresql.Driver"}
df.write.jdbc(url=url, table=raw_tweet_table_name, mode=mode, properties=properties)
...
query = tweet_stream.writeStream.outputMode("append"). \
foreachBatch(lambda df, id :
postgresql_all_tweets_data_dump(df=df,
epoch_id=id,
raw_tweet_table_name=raw_tweet_table_name,
count_acc=count_acc)).start()
stop_thread = threading.Thread(target=self.check_n_stop_streaming, args=(query, num_records, raw_tweet_table_name, ))
stop_thread.setDaemon(True)
stop_thread.start()
query.awaitTermination()
stop_thread.join()
答案 2 :(得分:0)
如果您只需要停止运行流应用程序,那么最简单的方法是通过Spark管理UI(您可以在Spark master的启动日志中找到它的URL)。
UI中有一个部分显示正在运行的流式应用程序,每个应用程序ID附近都有很小的(kill)
网址按钮。
答案 3 :(得分:-1)
现在是官方的,请在这里查看原始的apache文档 - http://spark.apache.org/docs/latest/configuration.html#spark-streaming