架构概览¶
Airflow是一个允许您构建和运行工作流的平台。工作流被表示为DAG(有向无环图),包含称为Tasks的独立工作单元,这些单元按照依赖关系和数据流进行排列。
DAG定义了任务之间的依赖关系,从而确定任务的执行顺序。 任务描述了要执行的操作,无论是获取数据、运行分析、触发其他系统还是其他操作。
Airflow本身对您运行的内容是无感知的 - 无论是通过我们某个提供商的高级支持,还是直接使用shell或PythonOperators作为命令,它都能愉快地进行编排和运行任何任务。
Airflow组件¶
Airflow的架构由多个组件组成。以下部分描述了每个组件的功能,以及它们是最小化Airflow安装所必需的组件,还是用于实现更好扩展性、性能和可扩展性的可选组件。
必需组件¶
一个最小的Airflow安装包含以下组件:
可选组件¶
一些Airflow组件是可选的,它们可以增强您的Airflow在可扩展性、伸缩性和性能方面的表现:
可选的工作节点,用于执行调度器分配的任务。在基础安装中,工作节点可能是调度器的一部分而非独立组件。它可以作为常驻进程运行在CeleryExecutor中,或以POD形式运行于KubernetesExecutor。
可选的 triggerer,用于在 asyncio 事件循环中执行延迟任务。在未使用延迟任务的基础安装中,不需要 triggerer。更多关于延迟任务的信息可以在 Deferrable Operators & Triggers 中找到。
可选的DAG处理器,用于解析DAG文件并将其序列化到元数据数据库中。默认情况下,DAG处理器进程是调度器的一部分,但出于可扩展性和安全性考虑,可以将其作为独立组件运行。如果存在DAG处理器,调度器就不需要直接读取DAG文件。更多关于处理DAG文件的信息可以在DAG文件处理中找到
可选的插件文件夹。插件是扩展Airflow功能的一种方式(类似于安装的软件包)。插件会被调度器、DAG处理器、触发器和网页服务器读取。更多关于插件的信息可以在Plugins中找到。
部署Airflow组件¶
所有组件都是Python应用程序,可以通过各种部署机制进行部署。
它们可以在Python环境中安装额外的软件包。这在安装自定义操作器或传感器,或通过自定义插件扩展Airflow功能时非常有用。
虽然Airflow可以在单台机器上运行并通过简单安装部署调度器和网页服务器,但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安全模型中阅读更多关于这些不同角色的信息。
在分布式部署的情况下,考虑组件的安全性方面非常重要。
webserver无法直接访问DAG文件。用户界面Code标签页中的代码是从元数据库读取的。webserver无法执行DAG作者提交的任何代码,它只能执行由部署管理员安装为安装包或插件的代码。运维用户仅能访问用户界面,只能触发DAG和任务,但不能编写DAG。
DAG文件需要在所有使用它们的组件之间同步 - 调度器、触发器和工作节点。DAG文件可以通过多种机制进行同步 - 典型的同步方式在我们的Helm Chart文档的管理DAG文件部分有描述。Helm chart是在K8S集群中部署Airflow的一种方式。
独立的DAG处理架构¶
在更复杂的安装环境中,安全性和隔离性至关重要,您还会看到独立的DAG处理器组件,该组件允许将调度器与访问DAG文件分离。如果部署的重点是解析任务之间的隔离,这种配置非常合适。虽然Airflow尚不支持完整的多租户功能,但可以用来确保DAG作者提供的代码永远不会在调度器上下文中执行。
注意
当DAG文件变更时,可能会出现调度器和工作节点看到不同版本DAG的情况,直到两个组件都同步完成。您可以通过确保在部署期间停用DAG并在完成后重新激活来避免此问题。如果需要,可以配置DAG文件夹的同步和扫描频率。请注意,如果更改这些配置,请确保您真正了解自己在做什么。
工作负载¶
一个DAG会运行一系列任务,你将看到三种常见的任务类型:
Operators,预定义的任务,您可以快速将它们串联起来构建DAG的大部分部分。
Sensors,一种特殊的Operator子类,专门用于等待外部事件发生。
一个经过TaskFlow装饰的
@task,这是一个打包成任务的自定义Python函数。
在内部,这些实际上都是Airflow的BaseOperator的子类,任务(Task)和操作符(Operator)的概念在某种程度上可以互换,但将它们视为独立的概念更有帮助 - 本质上,操作符和传感器是模板,当你在DAG文件中调用它们时,就是在创建一个任务。
控制流¶
DAGs 被设计为可多次运行,并且可以并行执行多个运行实例。DAGs 是参数化的,总是包含它们"运行对应"的时间间隔(数据间隔),但也可以包含其他可选参数。
任务之间有相互声明的依赖关系。在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确定任务运行顺序的依据。默认情况下,一个任务会等待其所有上游任务成功完成才会执行,但可以通过Branching、LatestOnly和Trigger Rules等功能来自定义这一行为。
要在任务之间传递数据,你有三种选择:
XComs("跨通信"),一个允许任务推送和拉取少量元数据的系统。
从存储服务上传和下载大文件(可以是您自己运行的,也可以是公共云的一部分)
TaskFlow API 通过隐式的 XComs 自动在任务间传递数据
Airflow 会在有可用空间时将任务发送到 Workers 上运行,因此无法保证您的 DAG 中的所有任务都在同一个 Worker 或同一台机器上运行。
在构建DAG时,它们可能会变得非常复杂,因此Airflow提供了几种机制来提高可持续性 - SubDAGs允许您创建可嵌入其他DAG的"可重用"DAG,而TaskGroups则让您可以在UI中直观地对任务进行分组。
用户界面¶
Airflow提供了一个用户界面,让您可以查看DAG及其任务的状态、触发DAG运行、查看日志,并对DAG问题进行有限的调试和解决。
这通常是查看整个Airflow安装状态的最佳方式,同时可以深入查看单个DAG,了解其布局、每个任务的状态以及每个任务的日志。