4.1 部署方案


4.1 部署方案

本节摘要:部署方案回答状态放哪、进程怎么拆、代码怎么送到执行侧。元数据必须进真正的数据库;调度器与 Worker 不要共命运;日志要让 Web 读得到。选 Local、Celery、Kubernetes 还是托管,取决于隔离需求与你愿不愿意养 Broker 和补丁,而不是取决于“是否云原生”这句空话。

你能学到什么

阅读完本节,你应当能够:

  1. 画出自己环境的元数据、执行、运行时三类状态落点
  2. 为十人以下团队给出可执行的第一套生产形态
  3. 说明托管移交了哪些进程责任、没移交哪些 DAG 责任
  4. 列出 DAG 代码与镜像同步失败时的症状

一、先画状态-责任图

原文把部署提升为状态主权再分配。元数据要强一致、长期留存:DAG 定义摘要、实例生命周期、变量、连接、XCom。执行状态在调度器里:解析结果、待放行队列、心跳。运行时状态在 Worker:临时文件、日志流、进程环境。把三类塞进同一块磁盘、同一个 Pod,故障域就焊死了。

最低生产线:PostgreSQL 独立安装或托管库;Web 与 Scheduler 分进程;执行器用 Local 仅当单机且能接受这台机器宕则任务全停。一越过单机,Broker 或 K8s API 就要进图。

责任方 落点 元数据 → PostgreSQL 主从 调度心跳 → Scheduler 进程 任务进程 → Worker 或 Pod 日志 → 共享存储或采集器 DAG代码 → 同步到解析与执行侧

不要把安装步骤理解成部署方案。方案是:库挂了谁切主、Worker 镜像谁构建、密钥从哪读。包管理器能装出进程,装不出这份合同。

图 四种常见形态

图 四种常见形态

二、代码如何到达执行侧

调度器要能读到 DAG 定义。Celery Worker 通常也要能 import 同一份代码。常见做法:把定义同步到共享卷、或打进镜像随发布走。两套时间差会导致“UI 已是新图,Worker 还在跑旧函数”。发布要把解析侧与执行侧做成一次版本。K8s 执行器把任务镜像当版本,更干净,也要求每次改胶水代码都出镜像,短迭代会烦。折中:基础镜像少变,DAG 文件用发布同步,重依赖才进镜像。

环境变量与连接:生产连接禁止进代码仓库。用密钥后端或平台注入。开发用独立的 Connection 名,不要共用生产 conn_id 再靠“运气没写错主机”。

形态 代码分发 主要运维负担
单机 Local 本机一份 机器与磁盘
Celery 多机同步或共享卷 Broker + Worker 版本一致
K8s Executor 任务镜像 镜像仓库与集群配额
托管 厂商约定的同步方式 IAM、网络、DAG 质量

三、第一套生产怎么砍

十人团队、几十条 DAG:托管 PostgreSQL + 单 Scheduler + 若干 Celery Worker + 远程日志,通常够。不要第一周上双调度器双可用区,除非已有合规要求。先把 catchup、池、日志三件事做对。

已经全在 Kubernetes 里跑数据作业:可以 Web/Scheduler 用 Deployment,执行器用 KubernetesExecutor 或 Celery on K8s。注意把元数据库放在集群外的托管库,避免集群维护日连账本一起停。

⚠️ 常见坑:用临时磁盘存日志和 SQLite,容器一重建,历史运行和日志一起蒸发,审计无法回放。
💡 关键直觉:部署图上少一个“日志箭头指向 Web 能读的地方”,上线第二天就会有人说 Airflow 没日志。

多团队共用一套 Airflow,要在部署期就想池、队列、RBAC,否则会在第 5 章才补围栏,那时 DAG 已经互相抢 Worker。能分集群就分:探索与生产不要同一调度器。原文的分层治理:开发允许 Local 与轻量库,生产才全量检查。Environment Profiles 一类方向也是在回应这件事情,动手时至少用两套部署落地,不必等某个版本口号。

网络:Worker 要能到达所有 Connection 里的主机,调度器通常不需要到达业务库,除非你在解析期违规查询。把出口权限给执行侧,不给 Web 侧随便连生产库,能减少界面被攻破后的横向移动。

四、验收部署的最小剧本

上线当天不跑业务 DAG,先跑三张探针。探针甲:空任务链,验证解析、建 Run、状态回写、日志能在 UI 打开。探针乙:只读外部连接,验证 Worker 网络与 conn_id。探针丙:故意失败且带回调,验证告警能到达 owner 频道而不是无人邮箱。三张都绿,再放第一条真实日报。缺探针就放业务,等于用真金去测保险丝。

DAG 代码同步要有版本文件或镜像摘要,调度器与 Worker 对得上。滚动更新允许短暂两版本时,任务必须向后兼容一个周期:新代码能处理旧 conf,旧代码不会因见到新字段崩溃。做不到就停调度、同步、再开,接受短暂延迟,不要接受随机函数体。

密钥注入:环境变量给保险库地址,不给密码明文。Connection 在 UI 或部署脚本登记一次,之后只改保险库。开发、预发、生产三套 conn_id 或三套实例,禁止“改一下 extra 指向生产”。Web 不要挂在公网裸奔,前面要有认证代理。这些像安全章,但部署时不做,安全章只能写愿望。

托管验收额外问:日志保留多久、能否导出、升级窗口谁通知、元数据库备份谁负责、网络出口如何加白名单。答不出“备份谁负责”,就还不是托管,只是把进程放到别人机器上的裸奔。

问题:单机 Local 能不能当一个月的生产?

任务少、可接受这台机器宕则当天报表停、已有 PostgreSQL 和远程日志,可以。把它写成明确的风险接受,而不是默默这么干。一个月后若 DAG 变多,迁移成本是加 Worker 和 Broker,不是推倒重写 DAG。这正是先写 DAG 再选执行器的好处:蓝图可带走,形态可换。

问题:必须用容器吗?

不是。容器解决的是依赖与隔离,不解决状态主权。虚拟机上的 Celery 一样是生产形态。容器化的正当理由是镜像可复现、与现有平台一致。没有平台团队硬上 Kubernetes,会把故障域从“一台 Worker”变成“集群里每一个你不理解的控制器”。

五、网络与密钥在部署图上的位置

部署图若只有进程框,会漏掉两条决定成败的线:Worker 到业务系统的出口,Web 到日志存储的入口。出口没开,探针乙失败。入口没开,探针甲看起来成功但 UI 没日志。密钥后端是第三条线:Scheduler 与 Worker 都要能取连接,Web 不一定要能读明文。三条线写成防火墙工单,与进程副本数一起验收。漏线的集群会在上线第二周出现“只有某队列失败”或“只有界面没日志”,被误诊为执行器 bug。部署方案的完整定义包含这三条线。托管环境同样要问清出口白名单怎么加,加不了就接不了内网数仓,形态再现代也没用。

六、形态切换时 DAG 不必重写

从 Local 到 Celery,改的是执行器配置与代码同步方式,不是 dag_id 与边。从 Celery 到 K8s,可能要补 executor_config 与镜像,仍不必重写窗口语义。这是动手优先的回报:合同写在 DAG 里,形态写在平台里。切换失败通常败在代码分发与日志,不败在 PythonOperator 语法。所以切换清单以分发与日志为第一项,执行器名为第二项。托管切自建或反向,同样如此。厂商差异在运维界面,不在 >>。有人想借切换之机“顺便重构全部 DAG”,那是把两件风险叠乘。先切形态,再重构。叠乘出问题,无法二分。二分能力是部署成熟度的标志,比是否云原生更硬。云原生救不了无法二分的变更。无法二分的变更,会把回滚变成考古。

七、代码分发验收口令

发布后立即在解析侧与执行侧核对同一版本摘要。对不上,暂停所有新 DAG,不要让新旧函数在同一窗赛跑。赛跑的结果不可复现。不可复现则测试无意义。无意义则 6.3 的闸门是摆设。摆设来自分发漂移。漂移来自“Worker 晚点同步没关系”的口头习惯。习惯在多机 Celery 上尤其致命。致命表现为偶发 ModuleNotFound 或偶发旧逻辑。偶发会让人怀疑随机。随机不是根因。根因是分发不是一次版本。一次版本是部署方案的牙齿。牙齿要在探针甲之前咬合。咬合失败,探针会绿在旧代码上,给你虚假毕业。虚假毕业后放真日报,真日报跑旧函数,数据错。错在分发,不在 SQL。SQL 作者会背锅。背锅会伤规范。规范在 6.1。6.1 要求幂等。幂等救不了旧函数少一列。少一列来自分发。分发在 4.1。4.1 把分发写成验收项。验收项用口令执行。口令是对摘要。对不上就停。停下是爱护窗口。窗口正在闭合。闭合时赛跑,账会裂。裂了要补。补要日历。日历又回到 2.1。一切部署问题最后都回到合同能否重放。重放要求函数体确定。确定要求版本对齐。对齐要求口令。口令要求人在发布后做一次核对。一次很便宜。便宜的核对能挡住昂贵的错账。错账对外。对外比内部偶发贵。贵的事先挡。挡在分发。分发在本节。本节把口令写进毕业考试旁边。考试是探针。口令是版本。两者都过,才算部署。只过探针,不过口令,是半套。半套会在滚动更新时咬人。咬人表现为两版本并存无人承认。承认来自摘要。摘要来自口令。口令要做。做了 4.1 才完整。完整才能谈 4.2。4.2 扩的是已对齐的版本。不对齐就扩,是把错误复制到更多机器。更多机器跑旧函数,错得更整齐。整齐不是正确。正确是对齐。对齐是口令。口令结束。

八、滚动更新窗口与分发口令同做

更新 Worker 的那一小时,分发口令每十分钟对一次摘要。对不上就暂停新 Run。暂停比赛跑便宜。赛跑不可复现。不可复现会让当天所有失败无法归因。无法归因会摧毁对平台的信任。信任用十分钟核对保护。核对写进滚动剧本。剧本与探针一起验收。验收不过,滚动不准开始。开始前先有摘要来源。来源是制品。制品是一次版本。一次版本是牙齿。牙齿在滚动窗口里反复咬。反复咬才能发现漂移。漂移发现得早,旧函数跑的窗口少。少则错账小。小则可补。补得过来,部署才算成年。成年结束“晚点同步没关系”。没关系结束于口令。口令结束 4.1 的最后一牙。牙结束半套。半套结束。形态切换仍不必重写 DAG。不必重写是回报。回报建立在口令上。口令结束本节。

本章回顾

  • 先分配三类状态的责任,再选进程拓扑
  • 生产账本用 PostgreSQL 或 MySQL,不要 SQLite
  • 调度器与 Worker 分命运,Web 可单独扩
  • 代码与镜像必须版本对齐
  • 托管只接管进程,不管窗口语义
  • 日志共享是部署验收项,不是优化项

下一节讨论活过单机故障时,每一层分别要备什么。


作者与出处
原作者: 灏天文库
来源:灏天文库
整理: 灏天文库整理
由灏天文库平台收录,内容或由平台用户上传,仅供学习交流
发布者: 作者: 灏天文库 转发
评论区 (0)
U