如何在单个Spark应用程序中启动多个流查询?

时间:2018-10-11 14:17:29

标签: apache-spark spark-structured-streaming

我已经建立了几个在EMR上运行的Spark结构化流查询,它们是长时间运行的查询,并且需要一直运行,因为它们都是ETL类型的查询,因此当我向EMR上的YARN群集提交作业时,我可以提交一个火花申请。因此,该spark应用程序应具有多个流查询。

我对如何以编程方式在同一个提交中建立/启动多个流查询感到困惑。

例如:我有以下代码:

case class SparkJobs(prop: Properties) extends Serializable {
  def run() = {
      Type1SparkJobBuilder(prop).build().awaitTermination()
      Type1SparkJobBuilder(prop).build().awaitTermination()
  }
}

我在主班里用SparkJobs(new Properties()).run()开枪

当我在Spark历史记录服务器中看到时,只有第一个Spark Streaming作业(Type1SparkJob)正在运行。

以编程方式在同一Spark提交中触发多个流查询的推荐方法是什么,我也找不到合适的文档。

3 个答案:

答案 0 :(得分:4)

由于您在第一个查询上调用awaitTermination,因此它将阻塞直到开始第二个查询之前完成。因此,您要启动两个查询,然后使用StreamingQueryManager.awaitAnyTermination

val query1 = df.writeStream.start()
val query2 = df.writeStream.start()

spark.streams.awaitAnyTermination()

除上述内容外,默认情况下,Spark使用FIFO调度程序。这意味着第一个查询在执行时会获取集群中的所有资源。由于您尝试同时运行多个查询,因此应切换到FAIR scheduler

如果您有一些查询应该拥有比其他查询更多的资源,那么您还可以调整各个调度程序池。

答案 1 :(得分:0)

这取决于您是要在任何查询停止/失败还是所有查询停止/失败时退出

如果退出任何查询,请使用 spark.streams.awaitAnyTermination()

如果退出所有查询:

选项 1:

val query1=ds.writeSteam.{...}.start()
val query2=ds.writeSteam.{...}.start()
query1.awaitTermination();
query2.awaitTermination();

选项 2:

val query1=ds.writeSteam.{...}.start()
val query2=ds.writeSteam.{...}.start()
spark.streams.active.foreach(x => x.awaitTermination())

选项 3:

while (!spark.streams.active.isEmpty) {
  println("Queries currently still active: " + spark.streams.active.map(x => x.name).mkString(","))
  spark.streams.awaitAnyTermination()
  spark.streams.resetTerminated()
}

答案 2 :(得分:-2)

val query1 = ds.writeSteam。{...}。start()

val query2 = ds.writeSteam。{...}。start()

val query3 = ds.writeSteam。{...}。start()

query3.awaitTermination()

AwaitTermination()将阻塞您的进程直到完成,这在流应用程序中永远不会发生,请在您上一次查询时调用它,以解决您的问题