从失败的Spark作业清除输出的最佳方法是什么?

问题描述

我正在运行多个Spark作业,这些作业从各个S3存储桶读取数据,转换为Parquet格式,然后写入单个S3存储桶以作为单个数据源从Athena进行查询。

作业可能由于多种原因而失败(OOM,S3节流等),并且当这样做时,它经常将数百或数千个part-*.snappy.parquet文件保留在目标S3存储桶中。我的输出数据也按如下方式进行分区:/year=2020/month=8/day=8/hour=0/。所有作业运行都写入同一文件夹,并且一个作业可能会在多个分区中产生结果。因此,我不认为可以使用overwrite模式,因为它会覆盖先前成功作业运行的结果。清理部分完成的作业是否有最佳实践?

我考虑过的一些选择:

  1. 每次作业运行都使用GUID在所有文件名中写入文件。这可用于手动查找失败的作业运行中的文件并将其删除。问题在于,据我所知,GUID不会暴露在Spark作业中,因此为失败的作业找到GUID(当然,无需手动检查)似乎是个挑战。

  2. 将文件写入不是最终目的地的位置,只有在作业成功完成后,才将这些文件移动到最终位置。

选项2似乎是合理的,但此ETL管道需要额外的组件。

作为Spark / AWS Glue的新用户,最好在我尝试重新发明轮子之前找出最佳实践。什么样的模式可以清除Spark失败的工作,它们的优缺点是什么?

解决方法

因此,每当我们使用spark写入数据时,我们都只需要传递文件夹路径,就无法控制文件名。现在考虑到这一点,您始终可以在写入目标目录时覆盖输出。

df.write.mode('overwrite').parquet(path)

这样,您的目标将始终被我们替换。

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...