问题描述
根据 Prefect 的混合执行模型,代理“监视任何计划的流程运行并在您的基础架构上相应地执行它们”,而执行器“负责实际运行任务 [...] 用户可以submit
功能和wait
他们的结果。”
虽然从高级设计的角度来看这是有道理的,但实际上这些部分是如何组成的?例如,如果我指定 Flow Run 应该使用 Docker Agent 和 dask Executor,那么 Agent 和 Executor 之间具体发生了什么交互?如果我使用 Docker 代理和本地执行程序怎么办?还是本地代理和 dask Executor?
简而言之,在每个组件中,即在服务器、代理和执行器上,流程的每一步究竟发生了什么?
解决方法
代理代表 Flow 可以并且应该在其上执行的本地基础设施,如该 Flow 的 RunConfig
所指定。如果 Flow 只应在 Docker(或 Kubernetes、ECS 或其他任何东西)上运行,则 Flow Run 仅由该代理提供服务。代理可以为多个流提供服务,只要这些流都由该特定基础设施支持。如果 Flow Run 没有绑定到任何特定的基础设施,那么 UniversalRun
是合适的,并且可以由任何代理处理。最重要的是,代理保证与流程相关的代码和数据永远不会被 Prefect Server 看到,通过向服务器提交运行流程的请求以及正在进行的流程更新。
另一方面,Executors 负责实际的计算:也就是说,实际运行构成 Flow 的各个 Task。 Agent 通过以适当的顺序调用 Tasks 上的 submit
并处理 Executor 返回的结果来管理高层的执行。因此,Executor 不了解整个 Flow,而只了解它从 Agent 接收到的 Tasks。单个 Flow 中的所有 Task 都需要使用相同的 Executor,但一个 Agent 可以在不同的 Flow 之间与不同的 Executor 通信。同样,Executor 可以为多个 Flow Runs 提供服务,但仅限于 Task 级别。
具体来说:
- 对于 Docker 代理和 Dask 执行器,将有一个 Docker 容器来管理 DAG 的解析并将状态报告返回给服务器。不过,每个任务结果的实际计算将在该容器之外进行,在 Dask 分布式集群上进行。
- 对于 Docker 代理和本地执行器,容器将执行与上述相同的角色。但是,任务结果的计算也将发生在该容器内(该代理的“本地”)。
- 对于本地代理和 Dask Executor,注册为代理的机器将管理 DAG 解析和与服务器的通信,作为该机器上的独立进程,而不是在容器内。不过,每个任务的计算仍会在外部,在 Dask 分布式集群上进行。
简而言之,代理位于服务器和执行器之间,充当 Flow Run 生命周期的保管人,并为每个其他组件划分关注点。