以DAG方式安排作业

时间:2015-12-17 09:55:21

标签: python linux cron scheduled-tasks airflow

我们有一个包含不同类型工作的系统。我们打电话给他们,例如:

job_1
job_2
job_3

它们都需要不同的参数集(和可选参数)。即我们针对不同的job_1(x) x=运行A, B, C ...job_2针对一组参数运行,这些参数取决于job_1(x)的结果,还job_2加载job_A(x)存储的数据。等等。

结果是依赖关系的树结构。现在,这些工作偶尔因某种原因而失败。因此,如果job_A的{​​{1}}失败,那么树的分支将完全失败并且不应该运行。所有其他分支都应该运行。

所有作业都是用Python编写的,并使用并行性(基于产生SLURM作业)。他们与cron一起安排。这显然不是很大,有两个主要缺点:

  • 调试非常困难。无论树中较高的作业是否失败,所有作业都会运行。如果不深入了解依赖关系,很难看出问题出在哪里。
  • 如果较高的作业(例如x=B)未完成job_A可能会被安排运行,并且会根据过时日期失败或运行。

为了解决这个问题,我们正在考虑调度或可视化的气流,因为它是用Python编写的,它似乎大致符合我们的需求。我看到了不同的挑战:

  • 作业的依赖关系树非常一般(即job_B取决于job_B)或非常宽(即job_A,100个参数取决于job_B(y)。在第一种情况下,可视化树将有大约10个叶子,但是会使调试非常困难,因为作业可能只是某个参数失败了。后一种情况下的可视化树将非常宽并且有大约300片叶子。它会更多准确但可视化可能难以阅读。我们可以过滤失败的工作,只看他们的依赖吗?
  • 我们在工作中有并行性(我们需要它,否则工作运行超过一天,我们希望每天重新运行整个批次)这会搞砸我们的日程安排吗?
  • 我们希望尽可能少地改变我们的工作和数据管理。
  • 我们能否以易于理解的方式实施接下来产生哪些工作的规则系统?

气流是否是一个不错的选择?我知道还有其他一些(luigi,Azkaban等)与Hadoop堆栈有些相关(我们没有使用它,因为它不是大数据)。需要多少黑客攻击?有多少黑客是明智的?

1 个答案:

答案 0 :(得分:2)

我真的不能说气流,但我可以代表路易吉。

luigi的简要概述: Luigi专为数据流和数据依赖而设计,就像气流一样,但是是在Spotify开发的。数据流中的每一步都表示为一个继承自luigi.Task的类,我们将每个步骤称为任务。每个任务由三个主要功能组成,并具有参数声明。这三个功能及其描述:

  1. 要求:在此功能中,您可以通过返回这些任务来指定手头任务所依赖的任务。
  2. 输出:在此函数中,您可以通过返回类Luigi.LocalTarget(或类似但远程用户)的对象来指定保存此任务结果的位置。
  3. 运行:在此功能中,您可以指定运行任务时实际发生的情况。
  4. 注意:luigi中央调度程序通过检查文件是否存在来知道任务何时完成 - 特别是在要运行的任务的requires函数中返回的任务的输出函数中指定的文件。

      

    我们可以过滤失败的作业,看看它们的依赖关系吗?

    Luigi记录传递给每个任务的所有参数以及每次运行每个任务的尝试。默认情况下,luigi不会保存日志,但您可以轻松地将其设置为。去年夏天我做了一个很大的luigi管道,我把它保存了。然后使用模糊字符串比较(使用Levenshtein库)删除重复的行并重新压缩日志,然后基本上搜索单词" error",如果它出现,那么它会发送一封电子邮件给我压缩的日志。

      

    我们在工作中有并行性(我们需要它,否则工作运行超过一天,我们希望每天重新运行整个批次)这会搞砸我们的日程安排吗?

    我在其中运行具有并行性的任务没有任何问题。有些库可能会导致问题,例如gensim。

      

    我们希望尽可能少地改变我们的工作和数据管理。

    您通常可以将大部分计算粘贴到luigi任务的运行功能中。

      

    我们能否以易于理解的方式实施下一步产生的工作的规则系统?

    我相信,是的。对于每个任务,您可以在任务的requires函数中指定它所依赖的任务。

    要考虑的其他事情是文档。 Luigi的文档相当不错,但它并没有尽可能多地流行起来。 Luigi的社区不是很大,也不是非常活跃。据我所知,Airflow相当可比,但它更新,所以可能暂时有一个更活跃的社区。

    Here是一个博客文章,由luigi撰写的博客文章与luigi和新的替代品之间进行了一些简短的比较。他的结论是:他们都很糟糕。包括Luigi。