如何使用 Prefect 中的任务、流和子流构建模块化数据流
如何使用 Prefect 中的任务、流和子流构建模块化数据流
以及如何在 Prefect 数据管道中定义状态和数据依赖关系
磷 反射是一个 协调平面 对于不断发展的数据世界。使用 长官 ,您可以编排任何数据流并观察周围发生的所有其他事情。通过在任何给定时刻观察数据堆栈中发生的情况,Prefect 可以让您了解数据流的当前状态,并允许您使用编排对其做出动态反应。
长官 有丰富的词汇来定义你的编排逻辑,包括 任务 , 流动 , 和 子流 ,以及状态和数据依赖关系。无论您是否在本地进程中运行数据流,您的数据流都能始终如一地工作, 异步循环 ,或在遥控器上 仪表板 或者 射线 簇。这篇文章将深入探讨 核心构建块 并解释它们如何帮助您构建模块化和可扩展的数据流。
任何数据流的基本构建块
在知府, Python 是 API .我们相信您的代码是您工作流程的最佳代表。但是为了组织这些步骤,管理它们的执行状态,并获取更多信息 可观察性 ,有两个核心构建块可作为编排的入口点:
- 任务 ——代表离散工作单元的(可选)函数;因为任务已经是最小的单位, 你不能从其他任务中调用任务 ,但您可以从您的任何 ( 父母 ) 流动。
- 流动 — 用于任何给定数据流或可执行/可调度流程的数据流、业务逻辑和编排规则的容器。
您可以根据您要实现的目标,以各种方式将任务、流程和子流程组合成可组合和模块化的工作流程。
返回值
任何 流动 或者 子流 可以返回 数据 和 状态 . 任务 可以额外返回 **PrefectFutures**
**** 当他们被提交给任务运行器时。让我们详细了解一下。
1) 返回数据
返回数据是什么意思? 每当您的流程或任务直接返回任何 Python 对象时,都会发生这种情况。例如,这是一个返回整数值的流程:
Prefect flow returning an integer value
这是一个数据流,其中任务和主要流程返回 pandas 数据帧:
Flow and tasks returning Pandas dataframes
当你运行这个( 例如,从本地终端或 Jupyter 笔记本 ),您的计算结果是一个熊猫数据框:
Pandas dataframe returned by a Prefect flow
返回数据 ( 而不是状态或期货 ) 是您调用任务或流时的默认行为。返回的值可以作为数据依赖项传递给任何下游任务甚至流:
Passing data between tasks
但是您也可以有一个不返回任何内容的流程:
“Hello world” in Prefect — flow returning nothing
您可以将 Prefect 流代码视为带有“附加”的纯 Python,仅当它变得有用时才应用。对于任何给定的工作流程,您可以根据需要尽可能多地利用 Prefect。
返回数据的好处:
- 简单 — Prefect 直接在流程运行过程中运行您的流程。
- 可读性 — 您的同事和合作者无需了解 Prefect 的任何内容即可理解此流代码 — 它只是 Python。
- 增量采用 — 您可以通过添加单个流装饰器将现有代码移动到 Prefect ( 并可选择通过 创建部署 从 CLI 安排该流程 )。
回归美好未来
什么是 **PrefectFuture**
?
**PrefectFuture**
是一个对象,表示在任务运行器中发生的计算结果。它同时拥有:
- 这 数据 由任务返回
- 这 状态 一个( 潜在并发或并行 ) 计算。
返回一个是什么意思 **PrefectFuture**
? 当您使用调用任务时 your_task.submit()
,它们被提交给一个任务运行器,它为访问任务的状态和结果创建了一个未来。
期货可以作为数据依赖传递给下游任务,即使任务被提交并行执行 仪表板
或者 射线
, 或并发执行 异步
:
未来.wait()
会给你 状态 任务运行计算未来的结果()
会给你返回值,即 数据 — 当您的任务失败时,返回的数据是异常消息。
Example showing how you can retrieve the state and return value from a Prefect future
, even for failed tasks
阻塞与非阻塞任务调用
既然你知道如何与 **PrefectFutures**
, 你可以更好地理解 ( 并且可能会欣赏 )任务运行者的好处。运行直接返回数据的流时,任何失败的任务运行都会 堵塞 进一步执行和 立即停止运行 ( 下图中的第一个流程 )。
相反,当提交任务以供任务运行程序执行时,阻塞调用 ( 返回一个 _PrefectFuture_
) 允许您使用所有任务运行整个流程。一项任务的失败不会阻止另一项任务的执行( 下图中的第二个流程 )。
Blocking vs. non-blocking task calls
返回状态✔️
什么是 **知府**
? 它是一个代表运行状态的对象。状态通常被称为 Prefect 编排的“货币”——它们决定了您的流程和任务在计划、提交和最终执行时的运行进度。有些状态表示重试、失败、完成、取消、崩溃等。
Prefect 允许您在任务和流程转换到特定状态时采取行动,并让您控制自动化数据流对计算结果的反应方式。例如,您可能想要:
- 当您的流程运行时收到通知 完成 执行或当底层基础设施 崩溃
- 随时触发某个过程 取消 流运行或当您的任务或流运行时 重试
- 根据特定类型采取行动 失败 .
这一切都归功于 Prefect 州丰富的词汇。
返回一个是什么意思 **知府**
目的? 任何时候你调用你的任务 return_state=真
参数,Prefect 将直接返回一个状态对象,您可以使用该对象基于您关心的状态更改构建自定义行为,例如任务或流失败或重试。以下是如何在两者中调用该参数的示例 任务 和 子流 :
上面的流程演示了如何在执行任务时返回状态,以及从流程运行过程中的流程。下面是一个示例,展示了在将工作提交给任务运行器以进行异步
关于返回数据、期货和状态的结论✔️
Prefect 为您提供构建块,您可以在需要时灵活地应用到您的工作流程中。
- 开始时,您可以在一个流程运行过程中运行所有内容并返回 数据 直接地。
- 当您需要根据特定的状态变化采取行动时,您可以利用
**知府州**
. - 当您想转向并发或并行执行时,您可以探索并开始使用
**PrefectFutures**
.
根据您的工作流程的需要使用尽可能多的 Prefect。
__ ** 笔记:** 要了解有关 Prefect 状态的更多信息并查看更多示例,请查看 以下概念文档 .
何时返回数据、期货或状态✔️
了解返回数据、状态和期货之间的区别后,让我们看看您可能更喜欢其中一种的常见用例。
何时返回数据
你什么时候回来 数据 直接地,您的 Prefect 任务或流程与本机 Python 函数的工作方式相同。这样做的好处是自然 蟒蛇 经验。不利的一面是,如果您的任务或子流程失败,则会急切地引发异常,并且您的工作流程会在故障发生后立即终止。
这种行为对于 顺序处理 ,例如,当您想要运行一些必须一个接一个地发生的数据转换时。如果之前的任何一个失败,您希望整个工作流程立即结束。
何时返回 **完美的未来**
当您想利用 Dask、Ray 或异步事件循环时,您可以将任务提交给任务运行器并获得以下好处 平行 或者 同时 执行。如果您需要更多控制来处理故障,这同样适用。 **PrefectFutures**
由于阻塞了任务运行提交调用,它提供了高度可定制的编排功能,这与在分布式设置中的本地工作方式相同( 例如,当向分布式 Dask 或 Ray 集群提交工作时 ),即使是异步任务和流 ( 利用 Python _异步_
图书馆 )。
何时返回 **知府**
✔️
如果您想根据特定的状态转换采取行动,状态就变得很重要。例如,如果某些 API 调用未返回任何数据,您可能希望提前完成流程运行:
下面是一个示例,展示了如何在重要任务成功完成时通过 Slack 获得通知:
最终状态确定
Prefect 根据返回值确定流程运行的最终状态。这就是它在实践中的含义——如果你的流程返回:
- 例外 = 运行标记为 失败的 ;每当您的任务或流程函数中引发异常时,都会发生这种情况——无论是由您明确引发还是意外引发
- 数据 = 如果您的流程运行返回一些表示数据的对象,并且没有任何故障中断此过程,则该运行被标记为 完全的 ✅
- 状态 = 如果您显式返回特定状态,可能基于某些条件,Prefect 将使用此显式状态标记流程运行✔️
- 没有任何 = 如果两者都不是 数据 也不 状态 返回,则:
- 只要某些任务或流程失败,即返回一个 例外 , Prefect 将运行标记为 失败的
- 如果没有引发异常,则运行标记为 完全的 ✅。
有关更多最终状态确定示例,请查看 以下文档页面 .
下一步
这篇文章介绍了使用 Prefect 任务、流和子流的可能性,以及在与数据和状态依赖项交互时可以做什么。
如果您想分享您的数据流故事或询问任何问题,您可以通过我们的 社区松弛 或者 完美话语 .
快乐的工程!
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明