如何确保写csv是完整的?

时间:2019-07-19 07:43:14

标签: java apache-spark spark-structured-streaming

我正在将数据集写入CSV,如下所示:

df.coalesce(1)
  .write()
  .format("csv")
  .option("header", "true")
  .mode(SaveMode.Overwrite)
  .save(sink);

sparkSession.streams().awaitAnyTermination();

我如何确定流作业终止时输出正确完成?

我有一个问题,如果我太早/晚终止,接收器文件夹将被覆盖并且为空。

其他信息:特别是如果该主题没有消息,则我的spark作业仍在运行,并用空文件覆盖结果。

2 个答案:

答案 0 :(得分:2)

  

如何确定当流作业终止时,输出是否正确完成?

Spark结构化流的工作方式是流查询(作业)连续运行,并且“当流作业终止时,输出正确完成”。

我要问的问题是流查询如何终止。是StreamingQuery.stop还是Ctrl-C / kill -9

如果以强制方式(Ctrl-C / kill -9)终止了流查询,那么,您将获得所需的内容-部分执行而无法确保输出正确,因为该过程(流查询)被强制关闭。

使用StreamingQuery.stop,流式查询将正常终止并写出当时的所有内容。

  

我遇到的问题是,如果我过早/延迟终止,接收器文件夹将被覆盖,并且该文件夹为空。

如果您终止得太早/太晚,由于流式查询无法完成其工作,您还会期望什么。您应该stop正常运行,然后才能获得预期的输出。

  

其他信息:特别是如果该主题没有消息,则我的spark作业仍在运行,并用空文件覆盖结果。

这是一个有趣的发现,需要进一步探索。

如果没有任何消息要处理,则不会触发任何批处理,因此没有作业,因此没有“用空文件覆盖结果”。(因为没有任务将被执行)。

答案 1 :(得分:1)

首先,我发现您没有使用writeStream,但我不确定您的工作如何成为流式工作。 现在,回答问题1,您可以使用StreamingQueryListener来监视流式查询的进度。有另一个StreamingQuery从输出位置读取。监视它。将文件放置在输出位置后,请在StreamingQueryListener中使用查询名称和输入记录数来适当地stop进行任何查询。 awaitAnyTermination应该停止您的spark应用程序。以下代码可能会有帮助。

spark.streams.addListener(new StreamingQueryListener() {
override def onQueryStarted(event: QueryStartedEvent) {
  //logger message to show that the query has started
}
override def onQueryProgress(event: QueryProgressEvent) {
  synchronized {
    if(event.progress.name.equalsIgnoreCase("QueryName"))
    {
    recordsReadCount = recordsReadCount + event.progress.numInputRows
    //Logger messages to show continuous progress
    }
  }
}
override def onQueryTerminated(event: QueryTerminatedEvent) {
  synchronized {
    //logger message to show the reason of termination.
  }
}

})

我也想回答您的第二个问题,就像Jacek的回答中所提到的那样,这是不可能的。