Apache spark 在将spark dataset.0写入hdfs时,如何具有幂等保证?
我有一个spark进程,可以写入hdfs(拼花文件)。我的猜测是,默认情况下,如果spark出现一些故障并重试,它可能会写入一些文件两次(我错了吗?) 但是,我应该如何在hdfs输出上获得幂等性呢 我认为有两种情况应该以不同的方式提出质疑(但请纠正我,如果你知道得更好,请进一步说明):Apache spark 在将spark dataset.0写入hdfs时,如何具有幂等保证?,apache-spark,hdfs,idempotent,Apache Spark,Hdfs,Idempotent,我有一个spark进程,可以写入hdfs(拼花文件)。我的猜测是,默认情况下,如果spark出现一些故障并重试,它可能会写入一些文件两次(我错了吗?) 但是,我应该如何在hdfs输出上获得幂等性呢 我认为有两种情况应该以不同的方式提出质疑(但请纠正我,如果你知道得更好,请进一步说明): 失败发生在写入一项时:我猜写入操作已重新启动,因此如果hdfs上的post不是“原子”w.r.t,则可能会写入两次以触发写入调用。机会有多大 失败发生在任何地方,但由于执行dag的方式,重新启动将发生在多个写入任
我认为这取决于你在工作中使用什么样的提交者,以及提交者是否能够撤销失败的工作。例如 当您使用apacheparquet格式的输出时,Spark期望committer Parquet是
ParquetOutputCommitter
的子类。如果使用此提交程序DirectParquetOutputCommitter
来添加数据,则无法撤消作业
如果您使用ParquetOutputCommitter
本身,您可以确保它扩展FileOutputCommitter
并稍微重写commitJob(JobContext-JobContext)
方法
以下内容是从中复制/粘贴的
OutputCommitter API:
setupJob()方法在运行作业之前调用,通常用于执行
初始化。对于FileOutputCommitter
,该方法创建最终输出目录,
${mapreduce.output.fileoutputformat.outputdir}
,以及一个临时工作空间
对于任务输出,_temporary,作为它下面的子目录。
如果作业成功,将调用commitJob()方法,该方法在默认的基于文件的
实现将删除临时工作空间并创建隐藏的空标记
输出目录中名为_SUCCESS的文件,用于向文件系统客户端指示该作业
已成功完成。如果作业未成功,将使用状态对象调用abortJob()
指示作业是否失败或被终止(例如,被用户终止)。默认情况下
实现时,这将删除作业的临时工作空间
这些操作在任务级别类似。在调用之前调用setupTask()方法
任务运行时,默认实现不会执行任何操作,因为它是临时的
为任务输出命名的目录是在写入任务输出时创建的
任务的提交阶段是可选的,可以通过从返回false来禁用
needsTaskCommit()。这使框架不必运行分布式提交
任务的协议,并且既不调用commitTask()
也不调用abortTask()
。
FileOutputCommitter
将在用户未写入任何输出时跳过提交阶段
任务
如果任务成功,将调用commitTask()
,这在默认实现中会移动
临时任务输出目录(名称中包含要避免的任务尝试ID)
任务尝试之间的冲突)到最终输出路径,
${mapreduce.output.fileoutputformat.outputdir}
。否则,框架将调用
abortTask()
,它删除临时任务输出目录
该框架可确保在对特定任务进行多次任务尝试时,
只有一个会被犯下;其他的将被中止。出现这种情况可能是因为
由于某种原因,第一次尝试失败了-在这种情况下,它将被中止,稍后,
成功的尝试将被承诺。如果尝试了两次任务,也可能发生这种情况
作为投机性副本同时运行;在本例中,第一个完成的
将被提交,另一个将被中止