如何只允许特定机器 运行 Luigi 中的任务

How to only allow a specific machine to run a task in Luigi

Machine A 可以访问 SQL 数据库,Machine B 可以访问 Google 驱动器。如果 UploadToDrive 依赖于 DownloadSQLData 某处,我如何确保任务在正确的机器上 运行?

当前 Machine A 运行s DoSomethingElseWithDataMachine B 运行s UploadToDrive 几分钟后。这很好,直到有一天 Machine A 可能无法正常工作,此时 Machine B 将尝试 DownloadSQLData 作为上游依赖项并失败。

class DownloadSQLData(luigi.Task):

    # ...

    def run(self):
        # Only Machine A can do this
        # ...

class TransformData(luigi.Task):

    # ...

    def requires(self):
        return DownloadSQLData(date=self.date)

class UploadToDrive(luigi.Task):

    # ...

    def requires(self):
        return TransformData(date=self.date)

    def run(self):
        # Only Machine B can do this
        # ...

class DoSomethingElseWithData(luigi.Task):

    #...

    def requires(self):
        return TransformData(date=self.date)

这个例子中的SQL数据库实际上不是SQL数据库,而是我们公司的旧系统。当未经授权的用户尝试访问它时,它不会优雅地失败,我们希望避免 Machine B 的任何尝试。

Luigi 本身不能做调度,即运行在某些机器上执行某些任务或在某个时间将任务调度到运行。话虽这么说,有很多方法可以实现你想要的。

解决方案 1: 让我们介绍可以访问机器 AB 的机器 C。使用一些工具 (https://wiki.python.org/moin/SecureShell) 机器 C 可以 运行 任务从 A 检索数据,在 C 上转换它,然后传输到 B 上传前。

方案二:这个方案很可能工作量太大and/or不可行设置机器A,B,C 在网络调度程序中(像 slurm https://www.schedmd.com/) with C as the head scheduler and specify A and B as certain types of resources (possibly SQL and GDrive). Then, from C, schedule slurm tasks as luigi jobs (https://github.com/pharmbio/sciluigi 这样的东西可以帮助解决这个问题)。这些 slurm 任务应指定每个任务所需的给定资源。那就是

您可以利用 luigi.task.externalize 在不同的机器上创建不同的任务堆栈 运行:

  • 机器A:
    • 下载SQL数据
    • 外部化(DownloadSQLData) -> TransformData -> DoSomethingElseWithData
  • 机器B:
    • 外部化(转换数据)-> UploadToDrive
    • 外部化(DownloadSQLData) -> TransformData -> DoSomethingElseWithData