我正在将数据集写入CSV,如下所示:
df.coalesce(1)
.write()
.format("csv")
.option("header", "true")
.mode(SaveMode.Overwrite)
.save(sink);
sparkSession.streams().awaitAnyTermination();
我如何确定流作业终止时输出正确完成?
我有一个问题,如果我太早/晚终止,接收器文件夹将被覆盖并且为空。
其他信息:特别是如果该主题没有消息,则我的spark作业仍在运行,并用空文件覆盖结果。
答案 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的回答中所提到的那样,这是不可能的。