我有一个工作流程,我将描述如下:
[ Dump(query) ] ---+
|
+---> [ Parquet(dump, schema) ] ---> [ Hive(parquet) ]
|
[ Schema(query) ] ---+
其中:
query
是对RDBMS的查询Dump
将结果query
转储为CSV文件dump
Schema
运行query
和 xcoms 其架构schema
Parquet
阅读csv
并使用schema
创建Parquet文件parquet
Hive
根据Parquet文件parquet
这种错综复杂的工作流程背后的原因是由于无法解决的限制并且超出了问题的范围(但是,理想情况下,它会比这简单得多)。
我的问题是在发生故障时回滚管道的影响。
这些是我希望在不同条件下发生的回滚:
dump
parquet
在工作流程中代表这一点,我可能会这样说:
[ Dump(query) ] ---+
|
+---> [ Parquet(dump, schema) ] ---> [ Hive(parquet) ]
| | |
[ Schema(query) ] ---+ | |
v v
[ DeleteParquetOutput ] --> [ DeleteDumpOutput ]
只有在发生错误并且转换到Parquet
时才会执行从DeleteParquetOutput
到DeleteDumpOutput
的转换,忽略其依赖项中的任何失败。
这应该可以解决这个问题,但是我认为通过这种错误处理逻辑可以使更复杂的管道在复杂性方面受到很大影响。
在继续讨论更多细节之前,我的问题是:在处理Airflow管道中的错误时,这可以被认为是一种很好的做法吗?什么可能是一种不同的(可能更可持续的)方法?
如果您对我希望如何解决此问题感兴趣,请继续阅读,否则随时回答和/或发表评论。
理想情况下,我想做的是:
让我们用给定的管道做几个例子。
我们反转DAG并使用其强制回滚过程(如果有)填充每个任务,获取此
+---> [ Dump: UNDO ]
|
[ Hive: None ] ---> [ Parquet: None ] ---+
^ |
| +---> [ Schema: None ]
+--- Start here
Hive
+---> [ Dump: UNDO ]
|
[ Hive: None ] ---> [ Parquet: UNDO (error) ] ---+
^ |
| +---> [ Schema: None ]
+--- Start here
有没有办法在Airflow中代表这样的东西?如果他们能够采用这种方法,我也愿意评估不同的工作流程自动化解决方案。
答案 0 :(得分:2)
所有运算符和传感器派生自的BaseOperator
类支持回调:on_success_callback
,on_retry_callback
和on_failure_callback
- 也许这些会有所帮助。
答案 1 :(得分:1)
似乎是一种处理错误的复杂方法。我认为最好将错误视为简单地停止DAG的当前运行,以便您可以解决任何问题并从停止的位置重新启动它。当然,您可以清理由特定任务创建的部分创建的文件,但我不会因为某些下游问题而收回整个管道。
以我工作的地方为例,不可否认,它使用的是不同的技术,但我认为是同样的工作流程:
使用我们当前的设置 - 如果有人意外更改Snowflake表的结构,我们将S3文件加载到唯一将失败的任务是最后一个(步骤3),因为表结构不再与CSV结构匹配。要解决这个问题,我们只需要将表的结构恢复到原来的状态,然后重新运行失败的任务。然后Airflow将文件从S3重新复制到Snowflake并成功。
您建议的设置会发生什么?如果最后一个任务失败,它将回滚整个管道并从s3存储桶中删除CSV文件;我们必须再次从源数据库下载该文件。如果我们简单地重新运行从s3复制到Snowflake的任务会更好,这样可以省去必须运行整个DAG的麻烦。