Loading Light/Dark Toggle
什么是 Airflow?面向数据团队的工作流编排

什么是 Airflow?

Scrapeless Web Unlocker 为 Apache Airflow 工作流可以协调的采集任务检索公开的网页内容。

Apache Airflow 是一个用 Python 定义、调度和监控工作流的开源平台。工作流描述了离散任务及其之间的依赖关系。对数据团队来说,这意味着提取任务可以在验证开始之前完成,而报表任务可以依赖被接受的数据,而不仅仅是依赖某个特定时间点的到达。

当采集程序成为共享服务时,这种区分就很重要。脚本可能能够正确检索页面,而其周边流程仍然缺乏明确的负责人、预期的采集频率或可靠的完成定义。Airflow 为这项工作提供编排。应用程序仍然负责决定返回数据的含义。

Airflow DAG 如何表示工作

Airflow DAG 对任务及其执行关系建模。这个缩写来自有向无环图(directed acyclic graph):连接具有方向性,依赖路径不会回到自身。一个任务可以依赖上游任务,多个相互独立的任务可以在共同的前置条件满足后变为可执行。

The Airflow 工作流模型 将任务定义与调度及其他运维设置结合起来。使用 Python 使得定义可以在版本控制中审查。依赖图的变更因此可以像应用业务逻辑的变更一样经过同样的评审流程。

将工作流定义与特定的一次执行分开。每日报表工作流是一个可复用的定义;针对某个特定报告区间的执行是一条运行(run)。同样,名为 extract 的任务在该运行中有其执行上下文。保持这些概念的区分有助于解释为什么两次运行可以有不同结果,即使它们共享相同的工作流代码。

任务边界应当遵循有意义的输出。下载源材料、检查其标识、提取记录以及写入被接受的记录是不同的职责。最初将一切合并为一个不透明任务也许很方便,但当一次采集产生不完整数据时,这会使任务状态的信息量变小。

调度器协调什么

调度器使用日程、任务依赖和记录的执行状态来协调符合条件的工作。执行细节取决于部署方式及其执行器。元数据数据库存储编排状态;它不应意外演变为所采集业务数据集的存储目的地。

Worker 执行分配给它们的应用工作。任务可能执行 Python、运行命令,或向另一个服务提交工作。Airflow 可以协调该提交流程,但独立服务的接收确认所描述的里程碑可能不同于其最终完成时间。你的任务定义应明确它承诺的是哪个里程碑。

一个 Web 界面公开工作流和任务状态,以便运维人员调查各次运行。只有当任务日志包含正确的上下文时,该界面才有用。记录来源、采集范围、输出位置和验证结果。避免记录运维人员在诊断工作流时不需要的凭证或完整内容。

工作流代码本身也有运维成本。将昂贵的采集和转换工作保留在预期的任务执行路径中。一个在加载时就执行远程工作的定义,会使控制平面更难运维,并模糊检查工作流与实际运行工作流之间的边界。

调度时间不同于观测时间

工作流的调度描述工作何时到期,而观测时间记录实际读取来源的时间。这两个值可能不同。一次延迟的运行可能会采集到当前页面,即使它的预期报告区间指向较早的时期。

在数据契约中显式地为这些时间戳命名。对一次公开价格观测而言,预期区间标识它所属的报表;观测时间戳标识页面提供该数值的时间。后来的执行无法重建更早的价格,除非确实存在提供该价格的历史来源。调度历史不是历史来源数据。

Python 区分 aware 和 naive 的日期时间对象(date-time objects)。在工作流边界应使用有意识的时区处理,而不是假设服务器本地时钟与业务报表时区一致。记录清楚由哪个时区定义一个报表日,尤其是在团队及其基础设施分布在不同地区时。

对于交换的时间戳, Internet timestamp conventions 提供了时间和偏移量的显式表示。即使时间戳格式保持一致,也不能解决其业务含义问题。字段名称和契约仍需说明它记录的是来源发布、采集、验证还是写入数据库的时间。

具有明确接收标准的采集工作流

网络采集工作流应基于被接受的输出推进,而不是基于已下载文件的存在。考虑一个团队每天收集公开的产品可用性,以进行库存对比。工作流从一份已批准的来源列表开始,其中的条目标识预期的产品和区域。

采集任务请求每个被允许的来源。 Scrapeless Web Unlocker 可以在这一边界提供公共页面内容,而 Scrapeless Web Unlocker capabilities 描述该服务的范围。Airflow 协调采集任务,而不会变成页面渲染器或 HTML 解析器。将检索到的响应与最终被批准用于报表的记录区分开来。

验证随后会检查页面标识和所需内容。成功下载的访问通知不应满足与产品页面相同的契约。缺失的可用性字段应产生一个明确的不完整结果,而不是被默默转换为缺货的观察结论。

下一个任务会提取规范化记录并将其与源上下文一起存储。只有被接受的输出才有资格进入报告。被拒绝的响应可以保留诊断引用以供调查,同时业务表仍然可解释。此设计使不完整的区间可见,而不是发布具有误导性的空白对比。

选择任务粒度与交接

任务粒度决定了操作员能够独立理解和控制的内容范围。一个有用的边界应当具有清晰的输入、明确的完成条件,以及下游任务无需猜测即可识别的输出。

对于大型数据集,在各个阶段之间传递一个稳定可访问的位置和描述性元数据,而不是将编排消息当作主要的数据存储。要在该位置中包含集合范围以及所采用的架构版本。下游任务应该能够确认其正在读取的是针对本次运行所期望的工件。

共享的可变文件名是歧义的常见来源。如果多次运行都写入同一个“最新”文件,延迟执行的下游任务可能会读取到来自其他时间区间的内容。应优先选择与一次运行或不可变数据分区绑定的输出标识,然后只在数据集通过验收之后,才更新任何“最新”指针。

重复执行同样需要一次应用程序决策。存储操作应当有一种稳定的方式来标识某个观测结果或已接受的批次。再次写入同一个已接受的批次,不应仅仅因为编排服务再次执行了某个任务就生成第二个业务事件。调度器无法替你推断出正确的记录标识。

Airflow 与单个定时命令的比较

当依赖关系和执行历史需要各自的运维模型时,Airflow 就能发挥价值。当某个命令负责一小块独立的工作单元且其输出可以被直接检查时,一个简单的定时命令就足够了。

问题计划命令Airflow 工作流
是什么开始这项工作的?时间匹配会调用一个命令。工作是由工作流程计划或受支持的触发器创建的。
依赖关系在哪里表达?在脚本内部或周边规范中。在工作流程的任务关系中。
应用程序必须定义什么?输入接受与输出含义输入接受和输出含义,以及任务契约。
团队必须操作什么?命令及其宿主环境。编排部署及其任务环境。

不要仅仅因为某个脚本每天运行就采用 Airflow。只有当团队需要查看和管理采集、验证、存储和发布之间的依赖关系时,才应该采用它。这些依赖关系才是你愿意承担额外的服务、配置和维护责任的原因。

Airflow 职责的边界

Airflow 协调的是有限的工作;它不会让外部数据源变得正确或完整。一个成功完成的任务仍然可能使用了错误的语言环境、选择了无关的页面,或者在其应用逻辑允许这种行为的情况下写入了重复的观测数据。

持续消息消费是另一个边界。一个工作流可以围绕数据流协调部署或有限的处理,但一个无限期运行的消费方与批处理任务有着不同的生命周期。在将其嵌入到计划调度的工作流之前,先决定由哪个系统来负责该生命周期。

成本也应写入合同中。 无爬取定价 当集合使用付费的外部服务时,应为每次运行设定一个有界的源范围。即使 DAG 本身看起来几乎没有变化,更频繁地调度更大的源列表也会改变集合需求。将预期的范围与工作流变更一同记录下来,以便审阅者评估其实际影响。

相关讨论 使用 Airflow 进行定时网页爬取 展示了收集阶段如何组合在一起。将其视为实现上下文,同时保持你自己的来源接受规则。示例工作流无法确定你的报告使用方可以容忍哪些缺失字段或不完整区间。

结论

Airflow 为重复性的数据工作提供了清晰的有向图、调度和执行历史。它的有用性依赖于描述真实输出的任务契约:一个被识别的页面、一批被接受的记录、一个已提交的数据集,以及从该数据集生成的报告。先从画清这些边界并命名相关时间戳开始。由此得到的工作流应当能让运维人员说明一次运行想要做什么、实际观察到了什么,以及最终有哪些内容对下游用户可用。

准备好连接收集与编排了吗?

围绕已接受的响应定义你的收集任务,然后让 Airflow 协调验证和交付。

今天注册即可获得 5 美元免费额度 — 无需信用卡.

领取您的 $5 额度 →

常见问题

问:Airflow 是数据库吗?

Airflow 是一个工作流编排平台,而其元数据数据库用于记录调度和执行状态。应将采集到的业务记录存储在单独的目标中,其数据模型和保留策略需要适配具体应用。

问:Airflow 会取代 cron 吗?

当某个作业发展成具有依赖关系和运行历史的工作流时,Airflow 可以取代简单的时间触发。对于能够在不依赖单独编排服务的情况下独立管理执行的命令,cron 仍然是一个合理选择。

问:任务成功是否能证明数据集是完整的?

任务成功只说明它满足了自身的成功条件。要在将某个采集区间视为“完成”之前,你的工作流必须显式检查数据源覆盖范围、预期字段,以及可接受的输出。

问:Airflow 会处理连续数据流吗?

Airflow 的设计围绕有限的工作流,包括由时间或事件触发的批处理工作流。持续运行的流式消费程序通常应放在流处理服务中,而在合适的场景下由 Airflow 协调其周边的有限工作。

参考资料