十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

长任务编排工具选型指南:Airflow、Prefect、Dagster 与 Temporal 的底层逻辑对比

长任务编排工具选型指南:Airflow、Prefect、Dagster 与 Temporal 的底层逻辑对比 1. 先把长任务编排这个词拆开你要解决的到底是哪个问题聊选型之前我得先说一个观察很多人把 Airflow、Prefect、Dagster、Temporal 放在一起比其实是把两个赛道的东西放进了同一个擂台。它们都能编排任务但编排这个词在数据工程和分布式系统里含义差别挺大的。我说的长任务至少可以分成三种形态。第一种是长周期的批处理任务。比如每天凌晨跑一次的数据同步、T1 报表计算、特征批量更新单个任务可能跑 20 分钟到几个小时不等。这种任务的典型特征是有明确的时间触发条件有固定的先后依赖关系失败后需要重试。这是 Airflow 的主场。第二种是长流程的业务/计算过程。比如一个用户发起退款需要经过风控审核、资金冻结、通知外部支付渠道、等待回调、解冻资金、记录流水整个流程跨多个服务、多个系统、可能持续几小时甚至几天。这种任务的典型特征是状态多、步骤多、要跟外部系统交互、中间有等待而且任何一步失败不能简单重跑整个流程。这种活儿真正的归宿是 Temporal。第三种是长耗时的计算任务。比如一个分布式训练任务跑 8 小时或者一个大规模数据处理 Spark Job 跑 40 分钟。它本身是一个任务不是一组任务编排工具对它的作用主要是启动、监控、失败后拉起、资源管理。这个场景跟前面两个有重叠但它往往更需要的是集群调度层面的能力而不是工作流层面的能力。搞明白自己是哪种形态再去看工具才有意义。否则你拿 Airflow 去编排一个跨微服务的退款流程会发现自己得写几百行 Custom Operator每个 Operator 都在轮询外部接口最后整个 DAG 变成一团浆糊。反过来你用 Temporal 去跑一个纯批量的 SQL 报表链又会觉得这不就是个带重试的 cron 吗至于吗。所以我这篇文章的核心目的不是告诉你哪个最好而是给出一套判断框架让你在自己的生产环境约束下能得出一个不那么后悔的结论。2. 四款工具的真实定位表面都是编排底层逻辑完全不同先说一个最容易踩的认知误区Airflow、Prefect、Dagster 是一家人Temporal 是另一家人。前面三个是调度器Scheduler 工作流描述框架的组合Temporal 是持久化执行引擎Durable Execution Engine。这不是简单的功能多寡问题而是底层设计哲学的巨大差异。2.1 调度器家族的共性基于 DAG 的静态/半静态建模Airflow、Prefect、Dagster 的核心抽象都是 DAG有向无环图。你在代码里定义好任务节点和依赖边调度器按照图的结构去触发、执行、跟踪状态。这套模型有两个隐含前提任务之间是依赖关系不是交互关系。A 完成后触发 BB 完成后触发 C这是单向的、无环的。如果业务上有等待用户确认后再继续这种需要暂停、甚至回退的场景DAG 模型就非常别扭。任务执行是提交-等待-收集结果的模式。调度器把任务分发给 workerworker 跑完上报状态。调度器本身不关心任务内部的微观状态它只看成功、失败、重试、跳过这几个粗粒度信号。2.2 Temporal 的差异把执行状态本身当作一等公民Temporal 的模型完全不同。它借鉴了 Cadence 的设计思想顺便说一句Temporal 的创始团队就是 Cadence 的核心成员核心是事件溯源Event Sourcing 确定性重放Deterministic Replay。你的工作流代码在 Worker 里执行框架会把执行过程中的每一个决策点以事件的形式持久化到后端存储Cassandra、MySQL、PostgreSQL 等。如果 Worker 挂了流程会停滞但重启后会从最后一个事件开始**重放Replay**代码恢复状态继续执行。因为代码逻辑是确定性的重放能精确还原到之前的执行位置。这意味着 Temporal 能够原生支持用await workflow.sleep(days)挂起一个流程几天几周用await workflow.execute_child_workflow(...)编排子工作流用 Signal 从外部向一个运行中的工作流实例发送消息比如用户已确认用 Query 在流程运行途中查询当前状态最直观的区别是思考方式Airflow 里你定义的是图Temporal 里你定义的是流程。图是一张静态的结构流程是一个可以暂停、等待、交互的动态过程。2.3 这个区别会直接决定你的技术选型天花板我见过不止一个团队用 Airflow 跑业务编排做到后面发现大量时间花在跟框架作斗争上。比如需要等待外部 webhook 回调Airflow 的解决办法是Sensors——轮询外部系统直到条件满足。但 Sensor 是占着 worker slot 的如果你同时有几百个流程在等回调就得把 Sensor 配置成modereschedule让它在等待期间释放 slot。这就是框架模型与业务需求不匹配时你需要靠技巧去弥补的例子。反过来如果是纯数据管道场景你用 Temporal 会有种杀鸡用牛刀的无力感。Temporal 没有内置的调度日历Cron 支持是后来加的没有开箱即用的任务依赖图可视化你需要在代码里用workflow.execute_child_workflow手动编织依赖关系——虽然灵活但可读性和可维护性远不如一张清晰的 DAG 图。所以我的第一个结论就是先分清你要的是图表驱动的批处理编排还是流程驱动的持久化执行。这个分岔路口走错了后面用什么工具都别扭。3. 调度器家族的守成者与改良派Airflow 和 Prefect如果最终确认你需要的是调度器那么 Airflow、Prefect、Dagster 之间怎么选又是一个层层递进的问题。我分开说。3.1 Airflow生态最成熟但设计还停在 2015 年Airflow 是 Airbnb 在 2014 年开源的项目2016 年进入 Apache 孵化器。它解决的问题非常朴素把一堆有依赖关系的 shell 脚本、SQL 语句、Python 任务用 DAG 管起来并提供调度、重试、日志、监控。它最大的资产是生态位。你在生产环境遇到的大部分数据工程问题几乎都能在 Stack Overflow、博客、同事的经验里找到 Airflow 的解法。无论你的数据库是 Snowflake、BigQuery、Redshift还是 Hadoop、Spark、Flink都有对应的 Operator。无论你想接告警、接血缘、接数据质量检查都有成熟的插件或者外挂方案。但它的问题也很明显调度器是单体瓶颈。Airflow 的 Scheduler 是单进程扫描 DAG 文件、计算调度时间表然后写入数据库。DAG 数量上到几百上千或者任务粒度很细、每分钟需要调度几万次的时候调度延迟会显著增加。我实测过DAG 数超过 800 之后调度的响应延迟可能从秒级退化到十几秒甚至几十秒取决于 DAG 解析复杂度。状态存储依赖数据库。任务实例状态存在元数据库里高并发下数据库读写会成为瓶颈。DAG 代码的模块级副作用是个坑。Airflow 会在调度器进程里导入所有 DAG 文件你的 DAG 文件里任何模块级别的代码比如建立数据库连接、调用外部 API都会在每次调度扫描时执行这会导致莫名其妙的性能开销和外部系统压力。但是我要替 Airflow 说句公道话如果在座各位团队只有 2-3 个人数据规模中等任务的依赖关系不超过几十个节点Airflow 就是最稳妥的选择。它的缺点在规模没到一定程度之前都是纸面上的理论问题而它的生态优势却是实打实的。3.2 Prefect把工程化体验补上了Prefect 是 2018 年出来的核心团队很多来自 NASA 的前数据工程团队。它把 Airflow 的很多痛点当成设计目标直接解决掉了。最核心的变化有几条第一状态存储和调度解耦。Prefect 2.x 把编排与执行拆得更开。流Flow和任务Task的定义用纯 Python 装饰器不需要像 Airflow 那样把业务代码塞进 Operator 或者PythonOperator的python_callable里。你写一个普通的 Python 函数加个task装饰器就是任务把这些任务用普通 Python 语法编排进一个函数加个flow装饰器就是流程。这种方式对开发者友好太多了不需要学习 Airflow 的 Operator 抽象层级。第二原生的动态依赖支持。Airflow 的传统模型DAG 静态定义里依赖必须在 DAG 文件解析时确定。如果你要根据前一个任务的输出来决定是否创建后一个任务代码会非常别扭。Prefect 2.x 在引用任务结果时依赖关系是在运行时确定的你可以在for循环里动态创建任务这让代码更符合直觉。第三自动重试和缓存机制更符合实际运维习惯。Prefect 的缓存可以通过输入参数、任务名称、tags 等维度控制对于同一个预处理任务被多个流程复用的场景可以避免重复计算。Prefect 的短板在于生态仍不如 Airflow。到目前很多第三方连接器尤其是企业级系统还是 Airflow 先行。开源的社区版和商业版Prefect Cloud之间存在功能断层。很多好用的功能比如自动化仪表盘、部分告警集成在 Cloud 版里才体验完整。你要是自托管开源版部分能力要自己补。我在生产环境用 Prefect 跑了快两年最直观的感受是它把 Python 开发者的心智负担降下来了。以前团队里新同学学 Airflow 需要搞清楚 DAG 文件、Operator、Task Instance、XCom 这一堆概念用 Prefect 的话只要会 Python 装饰器就能在一天内上手写流程。3.3 什么时候选 Airflow什么时候选 Prefect我的经验法则是这样团队里数据工程经验普遍较强但 DevOps/基础设施力量薄弱的选 Airflow 更稳。因为网上案例多踩坑资料多出问题你能搜到答案的概率更高。团队以 Python 开发为主、希望把编排代码和业务代码放得更近、愿意接受新工具带来的不便的选 Prefect。它的开发体验和对动态场景的支撑能力会让长期维护成本明显低于 Airflow。不过有一点要注意如果你的调度规模特别大——比如每天调度上万次、需要秒级调度窗口——Airflow 和 Prefect 其实都不是最优解。这种场景应该考虑更底层的调度系统比如内部基于大数据的调度平台或直接上更现代的架构。企业级场景里真的需要秒级调度的任务一般也不是数据管道而是在线服务侧的定时任务那应该用消息队列 Worker 的架构而不是搞个编排平台。4. Dagster数据资产视角的一次重构Dagster 和 Prefect 几乎是同一时期出现的它们都在解决 Airflow 的工程问题但走的路完全不一样。Prefect 的出发点是让开发者的代码体验更好Dagster 的出发点是让数据平台的管理者能更好地理解数据血缘、数据质量、资产状态。4.1 从任务到资产的思维转变Airflow 和 Prefect 的核心抽象是任务Task——你做一件事然后做另一件事。Dagster 的核心抽象是资产Asset——你有一张表、一个模型、一个数据集这些资产通过计算关系相互依赖。举个例子。传统 DAG 写法是raw_data 同步 → 清洗 → 特征工程 → 训练模型Dagster 的资产写法是asset def raw_data_table(...): ... asset def clean_table(raw_data_table): ... asset def feature_table(clean_table): ... asset def model(feature_table): ...你定义的不再是先跑谁、再跑谁而是每个产出物资产是怎么从其他资产计算来的。Dagster 会自己推导出它们之间的依赖关系自动构建执行图。这个视角的转变带来几个实打实的好处血缘关系自动维护。任何下游资产出了数据质量问题你可以直接追溯是哪个上游资产导致的。支持部分物化。你可以说我只想更新 feature_tableDagster 会自动判断需要先跑哪些上游资产。数据质量检查和资产生命周期绑定。每个资产可以定义自己的freshness_policy、retention_policy调度策略和生命周期管理更清晰。4.2 哪些团队能从中真正受益Dagster 适合的是把数据资产当作核心交付物的团队。典型特征团队负责的可交付物是一张张报表、一个个数据集、一个特征仓库而不是一次性的计算任务有明确的数据质量SLA需要对数据时效性做主动监控需要向数据消费者分析师、算法工程师提供清晰的数据目录和血缘视图反过来说如果你的场景非常简单就是几个定时脚本串起来Dagster 的资产模型可能反而显得绕。它的学习曲线在四款工具里我认为是最陡的——不是因为语法复杂而是因为你需要转变思维从我该怎么编排这个流程变成我的数据资产图谱长什么样。另外要吐槽的一点Dagster 的 UI 信息密度很高刚上手时可能会觉得眼花缭乱。它默认展示的是资产图谱而不是像 Airflow 那样的 DAG 树状图。对习惯了 Airflow 的人来说一开始找任务日志在哪里都要花点时间。但用熟练之后这个 UI 的数据洞察力确实是最强的。我个人的判断如果你的团队有专职的数据平台工程师并且很重视数据的可观测性和治理Dagster 值得押注。如果团队只是写写 SQL 跑跑脚本的定位Dagster 的优势发挥不出来反而会增加认知负担。5. Temporal工作流引擎跟调度器根本不在一个赛道前面花了三节讲调度器家族现在得认真聊聊 Temporal。它的设计思路跟上面三者有本质区别我单独拿一节出来讲是因为选型最容易出错的就在这里。5.1 持久化执行的核心机制与真实价值Temporal 的核心不是调度任务而是持久化你的流程状态。让我用一个生活化的比喻Airflow 像是一个项目经理拿着甘特图给每个人派活然后跟踪每个人干完了没有。如果项目成员中途跑了项目经理会重新找个人把活接着干完。Temporal 像是一个更底层的时间旅行者它把你整个项目过程中说过的每一句话、做过的每一个决策都录音了。哪怕整个团队消失了只要重新启动一个团队照着录音一遍遍重放就能恢复到消失前的状态继续干活。这个比喻对应到技术细节上就是Temporal 的 Worker 执行工作流代码时所有sleep、execute_activity、wait_signal这类操作都会生成事件写入存储。Worker 崩溃/重启/扩容缩容都不影响工作流实例的状态。流程停在那里等 Worker 恢复后从事件日志里重放到最近的位置然后继续执行下一步。这把长时间运行这个词的含义彻底改变了。在 Airflow 里一个任务跑 2 天调度器要守着它的状态整整 2 天。在 Temporal 里一个工作流等 2 天的外部回调几乎不占用任何资源——它只是睡着了状态都在存储里没有人需要一直守着它。5.2 用 Temporal 的正确姿势与常见误用Temporal 真正适合的场景是跨系统、跨服务的业务流程编排——订单履约、退款流程、K8s 资源审批、分布式发布、数据迁移管道多个阶段需要人工/外部系统干预等。判断标准就一条如果你的流程中出现了等待外部输入、在多个服务之间协调状态、需要对流程中的某一步单独做补偿这些字眼调度器会很吃力Temporal 会很舒服。但我见过不少团队反过来用。他们用 Temporal 跑纯 ETL 任务比如一个每天运行的 Spark SQL 任务链。最后发现Temporal 缺少像 Airflow 那样的调度日历界面、任务依赖图、数据处理插件生态他们需要自己写很多辅助代码。这就属于工具选型错位。还要特别提醒一个点Temporal 的代码写起来有额外的心智负担。因为它的核心要求是确定性——同一段工作流代码重放时必须产生完全相同的事件序列。这意味着你在工作流代码里不能用随机函数、取当前时间、直接查询外部系统等非确定性操作。这些操作必须封装在 Activity 里。新手上手时最常犯的错误就是在工作流函数里直接查数据库结果重放时数据不一致流程行为变得诡异。这一点在我接触的团队里引发了不少困惑很多人初次接触 Temporal 会觉得为什么这个限制那么多。但其实反过来想这些限制正是它能帮你把可靠执行这件事做到极致的原因。5.3 Temporal 的部署运维成本你要有心理准备Temporal 的部署比 Airflow 重。它的架构包含 Frontend、History、Matching、Worker 四个主要服务以及后端存储。虽然官方提供了自带的开发模式和 Helm Chart但生产环境要真正跑稳你需要对 Temporal 运行时的几个组件、数据分片、事件历史大小上限等有足够了解。事件历史也有一个隐藏的地雷单个工作流实例的事件数量如果增长到十几万条比如有大量循环并且循环次数很多的工作流会把存储和重放性能拖垮。解决办法是把大循环封装成单个 Activity避免在 Workflow 里产生海量事件。所以我的建议是如果团队里没有能理解分布式系统若干基础概念的工程师用 Temporal 要谨慎。它的学习曲线不是代码层面的而是运维和设计模式层面的。6. 生产环境决策框架五个问题锁定唯一选项说了这么多我知道大家最想要的是那个最终答案。设计一个决策流程你按顺序回答五个问题基本就能锁定该用哪款。问题一你的流程需要暂停和等待外部事件吗这个问题的本质是在问你要不要考虑 Temporal。如果答案是是——比如流程中间要等用户审批、等第三方回调、等人工确认而且等待时长可能是几小时甚至几天——那 Temporal 就是你绕不开的选项。调度器家族不是不能做Sensor、轮询但代价高、代码丑、长期维护痛苦。如果答案是否——所有任务都是内部计算、相互之间单向依赖没有中途挂起的需求——那 Temporal 就不是必要条件你应该在调度器家族里选。问题二你的核心资产是数据还是业务过程如果核心资产是数据表、模型、特征你把大部分精力花在保证数据质量、血缘清晰、数据时效上那 Dagster 是首选。它就是为了数据资产管理而设计的。如果核心资产是一个完整的业务结果比如退款成功并通知到用户数据的流转只是其中一个环节那 Temporal 更合适。或者你的数据管道也会涉及跨系统协调那可能 Docker 化的服务编排方式Step Functions、Temporal更靠谱。问题三你的团队是数据工程师主导还是应用开发主导?数据工程师习惯的思维模式是批处理、定时、依赖图他们用 Airflow/Prefect/Dagster 会更顺手。如果你的团队主要是后端 / 分布式应用开发习惯的是服务、API、状态机这类概念Temporal 会更亲切。我见过一个很典型的团队转型案例一个数据团队由后端工程师组成他们用 Airflow 写了几个月怨声载道觉得这什么玩意dependency 都要写在代码文件顶层跟业务逻辑混在一起。后来换了 Temporal整个团队的效率反而上来了。因为他们的心智模型本来就是流程 事件 状态。问题四你的调度规模有多大规模问题主要针对调度器家族DAG/Flow 数量 500任务粒度偏粗分钟级以上Airflow/Prefect 都轻松胜任数量 500-2000每分钟调度一次以上需要关注调度器的扫描能力和队列策略Prefect 的调度性能略好数量 2000或需要亚分钟级调度不管哪个调度器都有点勉强建议你重新思考架构记住一点调度规模大不等于任务数量多。真正考验调度器的是调度频率 × DAG 数量而不是单纯的任务总量。问题五你的团队愿意为运维复杂度付出多少运维成本排序大概是Airflow最简单≈ Prefect简单自托管略配置化→ Dagster中等→ Temporal复杂。Airflow 用 Docker Compose 就能拉起一个能用的环境生产环境再加个 CeleryExecutor Redis PostgreSQL 就够跑了。Temporal 的生产部署要复杂得多尤其是你要把它跑成高可用集群的时候。这里还要考虑长期维护的隐性成本工具社区是不是活跃、招人时候选人熟不熟悉这个工具、出了问题能不能快速找到答案。Airflow 在这些维度上依然是压倒性优势这也是为什么它在很多公司已经是事实标准。决策表四个工具踩点对照我做一个综合对照表按 1-5 分评价方便大家快速查看。评估维度AirflowPrefectDagsterTemporal调度能力4432生态/社区5433开发体验2444数据血缘/资产治理2351长流程/跨系统支持2325运维复杂度越低越好5432上手门槛越低越好4522注意这张表是我基于自己踩坑经历的主观评分不代表绝对正确。它在团队讨论选型时最大的价值是逼着每个人说出哪个维度对团队更重要而不是笼统地说我觉得谁比谁好。7. 混合编排的现实解不是非此即彼如果你觉得上面五个问题问完答案还是不止一个——那很正常因为真实生产环境从来不是单选题。实际落地中很多成熟团队用的是混合架构。7.1 调度器 工作流引擎的组合模式最经典的比例是用 Airflow 或 Dagster 管批处理数据管道用 Temporal 管跨服务业务流程。举例来说一家电商公司的数据团队是这么分的每天定时同步订单数据到数仓、清洗、生成报表用 Airflow 调度DAG 清晰调度日历明确用户发起退款后跨订单系统、支付系统、库存系统、通知系统的退款流程用 Temporal 编排wait_signal等待支付渠道回调compensate处理退款失败后的回滚这两个轨道互不干扰。数据管道大多跑在离线环境业务流程跑在在线环境。两套系统的监控告警、日志体系分开。负责数据的人不需要了解 Temporal负责业务编排的人不需要看 Airflow 的 DAG。这种组合的代价是团队要同时维护两套编排系统。但如果业务复杂度撑得起这套架构它的收益远大于成本——每个系统都在自己的领域里做到最优不需要在抽象上互相妥协。7.2 从 Airflow 迁往 Prefect/Dagster 的实操路径如果你现在已经在用 Airflow想迁移到 Prefect 或 Dagster我建议不要搞大爆炸式迁移而是分三步走。第一步选一个非核心、低风险的 DAG 做试点。比如一个每天跑一次、消费方只有两三个下游的表。用 Prefect/Dagster 重写它跟旧 DAG 同时运行对比结果。只是这一步就让团队在真实的代码差异、UI 体验、部署方式的感受上有据可依。第二步把改造优先级定义为谁最先痛谁先迁。凡是出现 Sensor 占用 slot、动态任务无法表达、DAG 代码依赖复杂导致解析变慢等问题优先作为迁移目标。没有症状的 DAG留在原地运行没必要为了迁而迁。第三步建立两条轨道的统一监控视图。哪怕用 Grafana 把两套系统的核心指标画在同一块仪表盘上至少能让运维同学不至于在故障时抓瞎。迁移最忌讳的是为了统一技术栈而把完全健康的系统推倒重来。工具只是手段稳定地交付数据价值才是目的。7.3 升级换代时的兼容性陷阱还有一个没多少人聊的话题从 Airflow 1.x 迁到 2.x 的坑我踩过上面提到的迁移往往不只是工具换工具还包含同工具的大版本升级。Airflow 1.10 年代的airflow.contrib模块在 2.0 后大量被移动或删除DAG 文件里如果用了旧 import 路径升级后全部报错。这需要你在升级前先跑一遍 import 扫描工具。Prefect 从 1.x 到 2.x 的 API 变化更大Flow、Task的使用方式全改基本等于重写。所以任何迁移项目都建议先做一次依赖和 API 使用面排查。把代码里用到的框架 API 列出来去目标版本比较提前评估改动量。这一步不花太多时间能避免迁移做到一半发现工程量远超预期的尴尬。8. 实战中的坑与体会四款工具我都踩过最后这块不写整齐的对比表格了专门挑几个我在真实生产环境里栽过的跟头给读者提个醒。每个坑都是我或者我认识的同行用时间和事故换来的。8.1 Airflow动态 DAG 生成是一把双刃剑我见过一个团队用 Python 脚本动态生成 DAG 文件——每天扫描某个配置表根据配置行数生成几百个结构相同、参数不同的 DAG。这个方案在 DAG 数量少的时候看起来很优雅但到后期调度器每天要重新解析几百个文件每次解析又有配置表的查询逻辑调度器的 CPU 和数据库负载双双飙升。更麻烦的是如果配置表中间某行数据出现问题会有一批 DAG 文件直接生成失败导致第二天的所有任务静默缺失——而且因为 DAG 文件是动态生成的缺乏版本控制很难快速回滚。我的建议动态 DAG 可以用但一定要缓存配置、控制生成频率并且把 DAG 文件纳入版本管理。不要每次都实时查表、实时渲染。8.2 Prefect状态存储的版本注意我在 Prefect 2.x 早期版本踩过一个大坑升级 Prefect 版本后旧的 flow run 状态在某些版本间无法正确读取导致历史运行数据看起来全部丢了。虽然实际上数据库里的数据还在但 UI 显示不出来在汇报和复盘时造成了很多麻烦。从此我养成一个习惯任何编排工具的升级先在一个临时环境里完整导入生产元数据快照验证 UI 显示、历史状态读取、重新调度触发都正常再动生产环境。特别是 Prefect 2.x 到 2.y 的小版本升级不要臆想小版本肯定兼容。还有一点Prefect 的本地/自托管模式下如果调度进程和 worker 进程的时区不一致或者系统时间跳变时间相关调度的行为会变得混乱。生产环境建议统一用 UTC 存储展示层再转本地时区可以少掉很多头发。8.3 Dagster资产模型的新鲜度策略别乱设Dagster 的 freshness policy 是个好功能但如果初学时不理解语义就乱加很容易出现调度永远追不上的情况。我见过一个团队设了某个资产 freshness_policy 为 1 小时但上游数据每天只更新一次。结果就是这个资产每次跑完还没到下一个小时就已经过期了系统频繁触发重跑下游计算资源被白白浪费。Dagster 的 freshness policy 设计初衷是确保数据在特定时间窗口内可用它依赖上游 cron 调度的配合。你需要在理解了上游任务调度频率的前提下再决定 freshness 的窗口大小。否则你以为在保护数据质量实际是在制造资源浪费。8.4 Temporal版本兼容和事件大小的日常纠缠Temporal 最让我头疼的点是工作流代码的版本升级。因为工作流可能挂起几天期间你的代码已经发布了新版本那么那些还没执行完的旧工作流实例怎么处理你不能直接改工作流代码因为旧实例重放时可能因为代码逻辑变更而走到不同的分支破坏确定性。官方提供了versioningAPI 来标记变更点但用起来需要很强的设计感。我见过团队的教训是上线前没有仔细考虑已经处于运行中但被长期挂起的工作流怎么办结果升级后一批旧实例行为异常需要人工干预。另一个实际运维问题是单个工作流的事件历史大小。如果一个工作流有大量循环并且循环体里产生很多事件事件存储会膨胀重放会变慢甚至超时。规则很简单循环尽量封装进一个 Activity把大量数据处理放在 Activity 里工作流代码只负责编排不负责计算。8.5 最后一句心里话最近这个领域热度上涨不仅仅是围绕工作流的讨论变多了也是因为数据平台和业务系统之间的边界越来越模糊。以前批处理调度和业务流程编排是老死不相往来的两个岗位现在大家发现数据管道跑得再好最终都要跟业务系统打交道。这也是我写这篇文章的初衷——选型别只看某一个工具而是看它在你的完整链路里处于什么位置。你不需要四项全精通也不需要一次选对永不再换。我自己的经验是先基于团队的现状和主要矛盾做选择然后强迫自己在一个工具上吃透至少一年把它的边界、脾气、隐藏能力都摸清楚再谈要不要引入第二个工具。工具太多运维负担是小事真正贵的是团队注意力的分散。
返回列表