如何停止火花流媒体工作?

时间:2015-09-15 09:41:16

标签: apache-spark spark-streaming

我有一个连续运行的Spark Streaming作业。我如何优雅地停止工作?我已经阅读了在作业监视中附加关闭钩子并将SIGTERM发送到作业的通常建议。

sys.ShutdownHookThread {
  logger.info("Gracefully stopping Application...")
  ssc.stop(stopSparkContext = true, stopGracefully = true)
  logger.info("Application stopped gracefully")
}

它似乎有效,但看起来不是最简单的停止工作方式。我在这里错过了什么吗?

从代码的角度来看,它可能有意义,但您如何在群集环境中使用它?如果我们启动一个火花流工作(我们在集群中的所有节点上分配作业),我们将不得不跟踪作业的PID和运行它的节点。最后,当我们必须停止进程时,我们需要跟踪作业运行的节点以及该进程的PID。我只是希望流媒体作业有一种更简单的工作控制方式。

4 个答案:

答案 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线程。

  • 使用流查询对象和累加器创建一个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