1、Prefect入门:工作流引擎概述、Prefect发展史、Prefect核心概念(Flow、Task、Deployment)、安装与Hello World

1.1 工作流引擎到底是个啥?

先聊聊工作流引擎。说白了,它就是帮你把一堆任务串起来、管起来的工具。你想想看,数据工程里经常有这种场景:先爬数据,再清洗,然后做特征工程,最后训练模型。每一步都可能失败,每一步都可能跑很久。

我刚开始做数据管道的时候,用的是Shell脚本加crontab。结果呢?某天凌晨三点,中间步骤挂了,后面的任务全白跑。第二天上班一看日志,头都大了。后来我意识到,我们需要一个能自动重试、能监控状态、能调度依赖的东西——这就是工作流引擎。

Prefect就是干这个的。它帮你定义任务之间的依赖关系,自动处理失败重试,还能实时告诉你每个任务跑到哪一步了。嗯,这里要注意,它不是唯一的选择,但它在易用性和功能之间找到了一个很好的平衡点。

1.2 Prefect的发展史:从学术项目到行业标配

Prefect的故事挺有意思的。它最早是2018年从一家叫Prefect Technologies的公司孵化出来的。创始人是Jeremiah Lowin,他之前在NASA做数据工程,深知现有工作流工具的痛点。

我记得Prefect 1.0刚出来的时候,最大的卖点是“动态工作流”——你可以在运行时动态生成任务,而不是像Airflow那样必须提前画好DAG。这个特性在当时很前卫。

到了2022年,Prefect 2.0发布,是一次彻底的重写。API更简洁,去掉了大量样板代码。我个人习惯用2.0之后的版本,因为写起来真的舒服很多。

现在Prefect已经成了数据工程圈的主流选择之一。社区活跃,文档完善,企业版也做得不错。如果你关注过2023-2024年的技术趋势,会发现很多公司都在从Airflow迁移到Prefect。

版本 发布时间 核心变化
Prefect 0.x 2018 初始版本,动态DAG概念
Prefect 1.0 2020 稳定版,Orion引擎
Prefect 2.0 2022 完全重写,简化API
Prefect 3.0 2024 事件驱动,增强监控

1.3 三个核心概念:Flow、Task、Deployment

Prefect的核心概念其实就三个:Flow、Task、Deployment。搞懂这三个,你就入门了。

1.3.1 Task:最小的执行单元

Task就是你的一个具体操作。比如“下载文件”、“清洗数据”、“发送邮件”。在Prefect里,你只需要在函数上加一个@task装饰器,它就变成了一个可被管理的任务。

我曾经在一个项目中,把一百多个函数都加上了@task,结果发现有些任务根本不需要重试或监控。后来我学乖了,只对关键步骤加装饰器。你想想看,不是所有函数都值得变成Task的。

from prefect import task

@task(retries=2, retry_delay_seconds=10)
def fetch_data(url: str) -> dict:
    # 这里写你的数据抓取逻辑
    response = requests.get(url)
    response.raise_for_status()
    return response.json()

1.3.2 Flow:任务的编排者

Flow把多个Task串起来,定义它们的执行顺序和依赖关系。你可以在Flow里写条件判断、循环、甚至动态生成任务。

我个人习惯把Flow看作一个“剧本”,Task是“演员”,Flow决定了谁先上场、谁后上场、演砸了怎么办。

from prefect import flow

@flow
def my_data_pipeline():
    raw_data = fetch_data("https://api.example.com/data")
    cleaned_data = clean_data(raw_data)
    result = analyze_data(cleaned_data)
    return result

注意看,这里没有显式声明依赖。Prefect会自动分析函数调用关系,构建出执行图。这就是它比Airflow方便的地方——你不用手动写>>操作符。

1.3.3 Deployment:让Flow跑起来

Deployment是Prefect 2.0引入的概念。它把Flow、调度规则、运行环境打包成一个可部署的单元。你可以把它理解成“生产环境配置”。

举个例子,你开发完一个Flow,想在每天凌晨3点跑一次,并且用Docker容器运行。这些配置就写在Deployment里。

from prefect.deployments import Deployment
from prefect.filesystems import GitHub

deployment = Deployment.build_from_flow(
    flow=my_data_pipeline,
    name="production",
    schedule={"cron": "0 3 * * *"},
    storage=GitHub(repository="my-org/my-repo"),
    work_queue_name="default"
)

核心关系总结:Task是“做什么”,Flow是“怎么做”,Deployment是“什么时候在哪做”。三者缺一不可。

1.4 安装与Hello World

好了,理论说完了,咱们动手试试。安装Prefect非常简单,一行命令搞定。

pip install prefect

我建议你在虚拟环境里装,别直接装到系统Python里。我曾经有一次把依赖搞乱了,花了半天才恢复。

装完之后,验证一下:

prefect version

如果看到版本号,说明安装成功。接下来写你的第一个Prefect程序。

1.4.1 Hello World:最简单的Flow

from prefect import flow, task

@task
def say_hello(name: str) -> str:
    message = f"Hello, {name}!"
    print(message)
    return message

@flow
def hello_flow(names: list[str]):
    for name in names:
        say_hello(name)

if __name__ == "__main__":
    hello_flow(["Prefect", "World", "Data Engineer"])

运行这个脚本,你会看到Prefect自动记录每次调用,生成运行ID,还能在终端看到实时日志。嗯,这里要注意,第一次运行可能会慢一点,因为Prefect要初始化一些元数据。

1.4.2 启动Prefect Server(可选)

如果你想看到漂亮的UI界面,可以启动Prefect Server:

prefect server start

然后在浏览器打开 http://localhost:4200。你会看到刚才运行的Flow记录,包括每个Task的状态、耗时、日志。我个人习惯开发时开着Server,方便调试。

小技巧:如果你不想启动Server,Prefect也支持“无服务器模式”。所有运行记录会保存在本地SQLite数据库里,用prefect orion database命令也能查看。

1.5 知识体系总览

下面这张图帮你理清本章的知识结构。我画的时候特意把核心概念放在中间,外围是安装和Hello World的步骤。

Prefect入门知识体系 Prefect工作流引擎 Task(任务单元) Flow(流程编排) Deployment(部署) 安装与配置 Hello World实战 Task是“做什么”,Flow是“怎么做” Deployment是“什么时候在哪做”

1.6 避坑指南

我曾经踩过的坑:

  • 版本混淆:Prefect 1.x和2.x的API完全不同。网上很多教程还是1.x的,注意看发布时间。我建议直接学2.x或3.x。
  • 装饰器顺序:如果你同时用@task和其他装饰器(比如@retry),记得@task要放在最上面。
  • 异步任务:Prefect原生支持异步,但新手容易在同步异步混用时出问题。刚开始建议全部用同步。

我的个人习惯:

  • 每个Flow文件只放一个Flow,方便管理和部署。
  • Task函数名用动词开头(fetch_data、clean_data),Flow用名词(data_pipeline)。
  • 开发阶段用prefect server start,生产环境用Prefect Cloud或自建Server。