雪花设置任务依赖

时间:2021-02-25 19:03:17

标签: scheduled-tasks snowflake-cloud-data-platform

我有一个任务需要在成功完成不同的前置任务后执行。

Say for example below three tasks triggers at same time and calls different stored proc.

CREATE TASK myschema.mytask_1
    WAREHOUSE = mywh
    schedule='USING CRON 0 8 * * MON America/Los_Angeles'
    as call myschema.MY_PROC_1();

CREATE TASK myschema.mytask_2
    WAREHOUSE = mywh
    schedule='USING CRON 0 8 * * MON America/Los_Angeles'
    as call myschema.MY_PROC_2();


CREATE TASK myschema.mytask_3
    WAREHOUSE = mywh
    schedule='USING CRON 0 8 * * MON America/Los_Angeles'
    as call myschema.MY_PROC_3();

但是我希望在以上三个任务都成功完成后执行下面的第四个任务。如果其中任何一个失败,第 4 次不应触发。总之,第四项任务取决于以上三项任务的完成。 我已经阅读了一些雪花文档,发现只能将一项任务设置为依赖项。现在可以依次考虑以下。此外,我不确定如何评估先前任务的成功完成以进一步进行。有人可以帮助我以更好的方式实现这一目标。非常感谢您对此的任何帮助。

CREATE TASK myschema.mytask_1
    WAREHOUSE = mywh
    schedule='USING CRON 0 8 * * MON America/Los_Angeles'
    as call myschema.MY_PROC_1();

CREATE TASK myschema.mytask_2
    WAREHOUSE = mywh
    AFTER myschema.mytask_1
    as call myschema.MY_PROC_2();


CREATE TASK myschema.mytask_3
    WAREHOUSE = mywh
    AFTER myschema.mytask_2
    as call myschema.MY_PROC_3();
    
CREATE TASK myschema.mytask_4
    WAREHOUSE = mywh
    AFTER myschema.mytask_3
    as call myschema.MY_PROC_4();

2 个答案:

答案 0 :(得分:0)

如果你连续运行任务,那么任何失败都会停止执行其余的任务,当下一个预定的执行到来时,它会从头开始并再次执行。根据您的逻辑,这可能不是您要寻找的行为。

关于第一个选项,这里一个可能的解决方案是利用流来启动第四个任务。这有点非正统,但你可以让它发挥作用。以下是研究尝试的基本步骤:

  1. 成功完成 SP 后,3 个并行任务中的每一个都需要将记录插入到单独的表中,因此它必须是 SP 中的最后一步。
  2. 这 3 个表中的每一个都需要创建一个 STREAM 对象。
  3. 您将任务安排为每分钟运行一次,并使用类似于以下代码的 WHEN 子句。
  4. 然后,您需要在对流执行一些 DML 语句的第 4 个任务之后执行一些其他任务,以便重置流。

第 3 步示例:

CREATE OR REPLACE TASK mytask_4
  WAREHOUSE = xxxx
  SCHEDULE = '1 MINUTE'
   WHEN SYSTEM$STREAM_HAS_DATA('mytask_1_stream') = True
    AND SYSTEM$STREAM_HAS_DATA('mytask_2_stream') = True
    AND SYSTEM$STREAM_HAS_DATA('mytask_3_stream') = True;

第 4 步示例:

CREATE OR REPLACE TASK mytask_5
  WAREHOUSE = xxxx
  AFTER myschema.mytask_4
INSERT * INTO log_table FROM mytask_1_stream;

CREATE OR REPLACE TASK mytask_6
  WAREHOUSE = xxxx
  AFTER myschema.mytask_4
INSERT * INTO log_table FROM mytask_2_stream;

CREATE OR REPLACE TASK mytask_7
  WAREHOUSE = xxxx
  AFTER myschema.mytask_4
INSERT * INTO log_table FROM mytask_3_stream;

就像我说的,这是一种解决方法,但在大多数情况下它应该可以很好地工作。还有一点,在这种情况下 mytask_4 永远不会使用任何计算,除非所有 3 个流都包含数据,这意味着您之前的所有 3 个任务都已成功执行。否则,任务将被跳过并等待下一分钟“再次检查”。如果您不经常运行前 3 个任务,也可以根据需要安排 mytask_4 减少运行频率。

答案 1 :(得分:0)

尽管 Mike Walton 建议的 Streams 解决方案很吸引人,但实现单个存储过程(可能在显式事务中,以便在发生错误时回滚)可能是一个更简单,因此更易于维护的解决方案。 话虽如此,如果性能是关键,您可能希望选择 Streams 选项,因为它可以保证每个存储过程中的不同代码段同时运行,而 Single-SP 将按顺序运行它们。