气流使固定间隔的作业变得容易。这篇文章寻求有关如何处理更复杂的调度要求的建议。
例如,假设我有从SFTP服务器提取文件并对它们执行某些操作的进程。源仅发布文件M-F。我希望dag表现为以下方式:
execution_date - 0
和- 1
和- 2
查找文件execution date - 0
吗?似乎实现起来不切实际,我需要做的只是设计它来提取碰巧存在的所有文件并每天运行,而无需参考特定文件。
问题是,如果我可以指定由execution_date
驱动的文件,那么我可以确切地看到已提取和未提取的内容,并可以使用重试功能。
想到的一种方法是每星期创建7个dag。但是我不喜欢那个主意。
另一种情况是,我是否希望该流程在每月的第二个星期日运行。有什么办法可以做这种事情?
编辑:
我认为实现此目的的最干净的方法是将dag设计为始终拉出日期为execution_date
的文件,但要直到星期一才触发sat和sun运行(并使用Trigger dag运算符这样做),并且使用带有BranchOperator和TriggerDagOperator的控制器dag来实现此目的。
答案 0 :(得分:2)
将DAG的var array1 = [
[1, 4, 6, 78],
[5, 3, 9, 21],
[11, 77, 9, 20],
];
var arr2 = [].concat.apply([], array1);
console.log(arr2);
设置为<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
,从星期一到星期五的每周的00:00运行。根据需要调整时间(前两个零)。
接下来,使用'schedule_interval':
作为DAG的输入方式。因此,在星期一,将执行DAG,并使用'0 0 * * 1-5'
,BranchPythonOperator
和execution_date - 0
查找文件。星期二至星期五,它只会查找execution_date - 1
。
我创建了一个简单的示例来向您展示我的意思。我希望这是一个充分的例子。让我知道是否可以进一步提供帮助。
execution_date - 2
答案 1 :(得分:0)
Zack的答案有助于解决此问题(因为必须使用分支运算符),但我要解决的解决方案是使用TriggerDagRunOperator
。
这是我为测试此方法而构建的dags。
目标达空
def alert(ti, **kwargs):
message = f"Execution date is {ti.execution_date}"
print(message)
with target_dag:
PythonOperator(
python_callable=alert,
task_id='target_task',
provide_context=True,
)
触发dag
def check_day(ti, **kwargs):
execution_date = ti.execution_date
if execution_date.minute % 7 == 0:
return ['weekday_trigger', 'saturday_trigger', 'sunday_trigger']
elif execution_date.minute % 7 in range(1, 5):
return ['weekday_trigger']
else:
return []
with trigger_dag:
check_day_task = BranchPythonOperator(
task_id='check_day_task',
python_callable=check_day,
provide_context=True,
)
weekday_trigger = TriggerDagRunOperator(
task_id='weekday_trigger',
trigger_dag_id='target_dag',
execution_date='{{ execution_date }}'
)
saturday_trigger = TriggerDagRunOperator(
task_id='saturday_trigger',
trigger_dag_id='target_dag',
execution_date='{{ execution_date + macros.timedelta(days=-1) }}'
)
sunday_trigger = TriggerDagRunOperator(
task_id='sunday_trigger',
trigger_dag_id='target_dag',
execution_date='{{ execution_date + macros.timedelta(days=-2) }}'
)
check_day_task >> [weekday_trigger, saturday_trigger, sunday_trigger]
为什么不只使用分支运算符?
我之所以喜欢这种方法,是因为我的目标dag不需要关心复杂的调度。它只需要关心执行日期。碰巧的是,在星期一,我们除了execution_date - 1
还要执行execution_date - 2
和execution_date
。但无论如何,目标dag的操作方式相同:它基于execution_date
做特定的事情。
如果我尝试将分支运算符合并到目标dag中,它将很快变得混乱。例如。如果您的目标任务有4个任务,那么您需要在星期一将这些任务重复两次。此外,dag运行历史记录的树形视图很丑陋,有很多跳过的任务,回填可能很奇怪。
总结
因此,在非星期一的工作日,我们的触发器dag触发target_dag
的执行日期与触发器dag相同。在周末,触发dag不会触发任何操作。在星期一和星期一,它会执行3次target_dag
运行。
注意:在测试计划的运行中,我用了几分钟来模拟几天。