架构概览¶
Airflow 是一个让你构建和运行*工作流*的平台。工作流表示为 DAG(有向无环图),包含称为 任务 的单个工作单元,这些单元按照依赖关系和数据流进行排列。
DAG 指定任务之间的依赖关系,这定义了执行任务的顺序。任务描述了要做什么,无论是获取数据、运行分析、触发其他系统,还是更多。
Airflow 本身对你运行的内容没有任何限制 - 它可以愉快地编排和运行任何内容,无论是通过我们其中一个提供程序的高级支持,还是直接使用 shell 或 Python 操作器 作为命令运行。
Airflow 组件¶
Airflow 的架构由多个组件组成。以下部分描述了每个组件的功能,以及它们是最低限度 Airflow 安装所必需的,还是实现更好的 Airflow 可扩展性、性能和可伸缩性的可选组件。
必需组件¶
最小的 Airflow 安装包含以下组件
可选组件¶
一些 Airflow 组件是可选的,可以提高 Airflow 的可扩展性、可伸缩性和性能
可选的*工作器*,它执行调度器分配给它的任务。在基本安装中,工作器可能是调度器的一部分,而不是单独的组件。它可以在 CeleryExecutor 中作为长期运行的进程运行,也可以在 KubernetesExecutor 中作为 POD 运行。
可选的*触发器*,它在 asyncio 事件循环中执行延迟的任务。在不使用延迟任务的基本安装中,不需要触发器。有关延迟任务的更多信息,请参阅 可延迟操作器和触发器。
可选的*DAG 处理器*,它解析 DAG 文件并将它们序列化到*元数据数据库*中。默认情况下,*DAG 处理器*进程是调度器的一部分,但出于可伸缩性和安全原因,它可以作为单独的组件运行。如果存在*DAG 处理器*,则*调度器*不需要直接读取*DAG 文件*。有关处理 DAG 文件的更多信息,请参阅 DAG 文件处理
可选的*插件*文件夹。插件是扩展 Airflow 功能的一种方式(类似于已安装的软件包)。*调度器*、*DAG 处理器*、*触发器*和*Web 服务器*都会读取插件。有关插件的更多信息,请参阅 插件。
部署 Airflow 组件¶
所有组件都是 Python 应用程序,可以使用各种部署机制进行部署。
它们可以在其 Python 环境中安装额外的*已安装软件包*。例如,这对于安装自定义操作器或传感器或使用自定义插件扩展 Airflow 功能非常有用。
虽然 Airflow 可以在单台机器上运行,并且只需部署*调度器*和*Web 服务器*即可进行简单安装,但 Airflow 的设计目标是可伸缩和安全,并且能够在分布式环境中运行 - 其中各种组件可以在不同的机器上运行,具有不同的安全边界,并且可以通过运行上述组件的多个实例进行扩展。
组件的分离还可以通过隔离组件以及允许执行不同的任务来提高安全性。例如,将*DAG 处理器*与*调度器*分离可以确保*调度器*无法访问*DAG 文件*,并且无法执行*DAG 作者*提供的代码。
此外,虽然一个人可以运行和管理 Airflow 安装,但在更复杂的设置中,Airflow 部署可能涉及与系统的不同部分交互的各种用户角色,这是安全部署 Airflow 的一个重要方面。这些角色在 Airflow 安全模型 中有详细描述,通常包括
部署管理员 - 安装和配置 Airflow 并管理部署的人员
DAG 作者 - 编写 DAG 并将其提交给 Airflow 的人员
运维用户 - 触发 DAG 和任务并监控其执行的人员
架构图¶
下图显示了部署 Airflow 的不同方式 - 从简单的“单机”和单人部署,到具有独立组件、独立用户角色以及更隔离的安全边界的更复杂部署。
下图中不同连接类型的含义如下
**棕色实线**表示*DAG 文件*的提交和同步
**蓝色实线**表示部署和访问*已安装软件包*和*插件*
**黑色虚线**表示*调度器*对工作器的控制流(通过执行器)
**黑色实线**表示访问 UI 以管理工作流的执行
**红色虚线**表示所有组件访问*元数据数据库*
基本 Airflow 部署¶
这是 Airflow 最简单的部署,通常在单台机器上运行和管理。这种部署通常使用 LocalExecutor,其中*调度器*和*工作器*位于同一个 Python 进程中,并且*调度器*直接从本地文件系统读取*DAG 文件*。*Web 服务器*与*调度器*在同一台机器上运行。没有*触发器*组件,这意味着无法延迟任务。
这种安装通常不区分用户角色 - 部署、配置、操作、编写和维护都由同一个人完成,并且组件之间没有安全边界。
如果你想在单台机器上以简单的单机设置运行 Airflow,则可以跳过下面更复杂的图表,直接转到 工作负载 部分。
分布式 Airflow 架构¶
这是 Airflow 的架构,其中 Airflow 的组件分布在多台机器上,并且引入了各种用户角色 - *部署管理员*、**DAG 作者**、**运维用户**。你可以在 Airflow 安全模型 中阅读有关这些不同角色的更多信息。
在分布式部署的情况下,重要的是要考虑组件的安全方面。*Web 服务器*无法直接访问*DAG 文件*。UI 的“代码”选项卡中的代码是从*元数据数据库*中读取的。*Web 服务器*无法执行*DAG 作者*提交的任何代码。它只能执行由*部署管理员*作为*已安装软件包*或*插件*安装的代码。**运维用户**只能访问 UI,并且只能触发 DAG 和任务,但不能编写 DAG。
所有使用 DAG 文件的组件(调度器、触发器 和 工作器)之间都需要同步这些文件。可以通过各种机制同步 DAG 文件 - Helm Chart 文档的管理 DAG 文件中描述了同步 DAG 的典型方法。Helm Chart 是在 K8S 集群中部署 Airflow 的方法之一。
独立的 DAG 处理架构¶
在更复杂的安装中,如果安全性和隔离性很重要,您还会看到独立的 dag 处理器组件,该组件允许将 调度器 与访问 DAG 文件 分离开来。如果部署重点是在已解析任务之间进行隔离,则此方法适用。虽然 Airflow 尚不支持完整的多租户功能,但它可以用来确保永远不会在调度器的上下文中执行 DAG 作者提供的代码。
注意
当 DAG 文件发生更改时,在两个组件都赶上之前,调度器和工作器可能会看到不同版本的 DAG。您可以通过确保在部署期间停用 dag 并在完成后重新激活来避免此问题。如果需要,可以配置 DAG 文件夹的同步和扫描频率。如果您要更改配置,请确保您真的知道自己在做什么。
工作负载¶
DAG 通过一系列 任务 运行,您将看到三种常见的任务类型
操作器,预定义的任务,您可以快速将它们串在一起以构建 DAG 的大部分部分。
传感器,操作器的一个特殊子类,完全用于等待外部事件的发生。
使用 TaskFlow 装饰的
@task
,这是一个打包为任务的自定义 Python 函数。
在内部,这些实际上都是 Airflow 的 BaseOperator
的子类,任务和操作器的概念在某种程度上是可以互换的,但将它们视为独立的概念是有用的 - 本质上,操作器和传感器是 模板,当您在 DAG 文件中调用一个时,您就是在创建一个任务。
控制流¶
DAG 被设计为可以多次运行,并且可以并行运行多次。DAG 是参数化的,始终包含它们“运行”的时间间隔(数据间隔),但也包含其他可选参数。
任务 声明了彼此之间的依赖关系。您将在 DAG 中看到这一点,可以使用 >>
和 <<
运算符
first_task >> [second_task, third_task]
fourth_task << third_task
或者,使用 set_upstream
和 set_downstream
方法
first_task.set_downstream([second_task, third_task])
fourth_task.set_upstream(third_task)
这些依赖关系构成了图的“边”,以及 Airflow 如何确定运行任务的顺序。默认情况下,任务将在其所有上游任务成功后才会运行,但这可以使用 分支、仅限最新 和 触发规则 等功能进行自定义。
要在任务之间传递数据,您有三种选择
XComs(“跨通信”),一个可以让任务推送和拉取少量元数据的系统。
从存储服务(您运行的服务或公共云的一部分)上传和下载大文件
TaskFlow API 通过隐式 XComs 自动在任务之间传递数据
Airflow 将任务发送到工作器上运行,因为空间变得可用,因此不能保证 DAG 中的所有任务都将在同一个工作器或同一台机器上运行。
在构建 DAG 时,它们可能会变得非常复杂,因此 Airflow 提供了几种机制来使其更具可持续性 - 子 DAG 允许您创建可“重复使用”的 DAG,您可以将它们嵌入到其他 DAG 中,而 任务组 允许您在 UI 中直观地对任务进行分组。
用户界面¶
Airflow 带有一个用户界面,可以让您查看 DAG 及其任务正在做什么、触发 DAG 的运行、查看日志,以及对 DAG 的问题进行一些有限的调试和解决。
它通常是查看 Airflow 安装整体状态的最佳方式,以及深入了解各个 DAG 以查看其布局、每个任务的状态以及每个任务的日志。