5.2 持续集成与部署


5.2 持续集成与部署

本节摘要:持续集成回答「这段代码能不能合并」,持续部署回答「验证过的代码怎么到达生产」。本节搭一条数据项目够用的最简流水线:合并请求触发编译检查与受影响模型的选择性测试,绿灯才准合并;合并后自动发布到生产。重点讲清数据语境下 CI 与软件 CI 的两个不同——选择性执行与「数据验证慢」带来的节奏差异。

合并请求是第一道闸门

软件项目的习惯这里完全适用:任何代码变更不直接进主干,而是走合并请求,由流水线先体检。区别在体检单上——软件项目跑单元测试,数据项目跑的是「编译检查加模型测试」,而且有个关键差异:全量测试太慢,必须选择性执行。

一个几百个模型的项目,全量测试跑下来可能一小时起步;如果每个合并请求都全量跑,开发节奏直接被流水线拖死。dbt 的选择性执行解决这个问题:给定改动模型的清单(从合并请求的文件差异里解析出来),只跑「这些模型及其下游」——上游没变,不必重验;下游全验,因为改动的影响沿着依赖图向下传播。

# 合并请求流水线的核心三步(示意) # 第一步:编译检查——语法与依赖图问题在这里现形 dbt compile --select state:modified+ # 第二步:只跑受改动影响的模型(自身加全部下游) dbt build --select state:modified+ # 第三步:新鲜度检查——顺带确认源数据到货正常 dbt source freshness

三步里的状态选择参数是关键:它让 dbt 自己判断「哪些模型相对于上一次已构建的状态发生了变化」,配合加号表示「连同下游」。这条命令组合是数据 CI 的标准姿势,名称叫得直白——瘦 CI(slim CI):只验证需要验证的部分。

流水线的反馈直接挂在合并请求上:绿灯放行,红灯附上失败明细(哪个测试、返回了几行问题数据)。评审者看代码差异,流水线看行为差异,两道关都过才合并。

持续部署:数据语境的特殊性

合并后的发布环节,数据项目与软件项目的差异就显出来了。软件的部署发布的是代码,部署完即生效;数据的部署发布的是代码加数据——新代码要等下一次构建才会产生新数据,而数据验证比代码验证慢得多。

因此数据项目的部署节奏常分两拍:

第一拍,代码发布。 合并后自动把新代码部署到生产环境(或部署到一个待激活的状态)。这一拍很快,分钟级。

第二拍,数据生效与验证。 下一次生产构建跑完,新代码才真正产出了数据。这一拍之后要有一次「生效验证」:核对关键模型的行数与核心指标和上一版代码的产出在预期范围内(逻辑变更的模型有预期差异,其余模型应该完全一致)。验证通过,发布才算闭环。

两拍之间的空档就是回滚窗口:如果第二拍的验证发现问题,回滚代码很轻(Git 回退再发布),但被新逻辑覆盖的数据需要修复——增量模型可以用「回拨水位重跑」补救(4.4 节档案三的手法),全量物化的模型等下一次构建自然覆盖。发布高风险逻辑变更时,选一个出问题后有足够修复时间的时点(比如工作日早上而不是周五晚上),这是数据发布排期的第一条常识。

图:一次变更从提交到生效的完整时间线

图:一次变更从提交到生效的完整时间线

一条最简流水线的落地清单

不依赖托管平台,用开源工具搭的最小可用版本,按顺序配五件事:

  1. 触发器:合并请求创建或更新时触发流水线(Git 平台的流水线机制都支持);
  2. 凭据注入:流水线从密钥管理系统读取集成环境的凭据,注入环境变量(5.1 节的规矩);
  3. 体检三步:编译检查、状态选择构建、源新鲜度,失败即红灯;
  4. 结果回帖:把流水线结果与失败明细回帖到合并请求,评审者不需要去别处看日志;
  5. 主干发布:合并后自动执行生产部署脚本(或触发托管平台的任务),部署动作本身幂等——重复执行无副作用。

这套清单在项目小于百个模型、团队小于十人时完全够用。规模再上去,值得买的东西主要是两样:托管的执行环境(免维护)与执行历史的可视化(免翻日志)——按 1.2 节的取舍框架,按人力成本算账即可。

💡 关键直觉:CI 的本质不是「自动化跑测试」,是把「合并权」从人的自觉移交给流水线的标准。没有 CI 时,能不能合并取决于评审者的耐心与眼力;有 CI 后,能不能合并取决于一个可复现的体检结果。人的判断留给「这段逻辑对不对」,机器的判断负责「这套代码跑不跑得动、过不过得了验收」。

CI 运行的两个实操疑问

流水线跑一次要花多少钱、多长时间

这决定了 CI 的节奏设计。时长方面,瘦 CI 的体检(编译加选择性构建)通常在几分钟到二十分钟之间,取决于改动模型的下游规模——改一张底层贴源表,下游几十个模型全部要跑,体检自然长;改一张末端报表模型,几分钟收工。成本方面(按扫描计费的仓库),体检消耗的是真实算力,受影响链越长越贵。两个工程约束由此而来:改底层模型挑低峰期提请(下游链体检便宜些),以及给流水线设并发上限(防止多个合并请求同时跑体检把仓库算力挤爆)。

测试在 CI 里失败,但本地是好的,信谁

先别急着下结论,这种「本地绿、CI 红」的差异本身就是线索,常见成因按概率排:集成环境的数据形态与本地不同(5.1 节案例的变体——本地只有自己造的几行数据,CI 面对真实快照);依赖版本差异(本地手滑升级了某个包,CI 按锁文件装旧版);改动模型的上游在 CI 环境处于不同的构建状态。排查动作是让两边环境尽量对齐后重放——多数情况下,CI 环境更接近真相,因为它更接近生产。这背后的原则值得记住:本地验证证明「代码能跑」,CI 验证证明「代码在接近生产的环境里能过验收」,合并决策看后者。

合并后部署失败了,怎么回滚

回滚的粒度是「代码提交」而不是「环境状态」:把主干回退到上一个已知正常的提交(或直接还原那次合并),流水线重新部署——这就是 5.1 节「三套环境跑同一份代码」红利的兑现时刻:环境本身无状态(状态全在 Git 与仓库里),回滚等于把代码指针拨回去。需要预案的是数据侧:被新逻辑跑过的表,按 4.4 节的手法回拨水位重跑即可,全量物化的表等下一次构建自动覆盖。

变更积压时,允许不体检直接合并吗

不允许——这个口子一开,CI 就退化成「建议」。真正的解法在别处。第一,把大变更拆小:多数积压源于一次合并请求里塞了十个模型的改动,体检要跑完整下游链,又慢又容易红;拆成按模型逐个提交,每条的体检范围小,并行度反而上去了。第二,区分风险等级:只改模型描述与注释、不碰 SQL 的变更,可以配置成只跑编译检查不跑构建——体检单跟着风险走,而不是一刀切全跑。第三,积压本身是信号:说明评审带宽或体检时长出了问题,值得回头看一遍流水线的耗时分布。数据项目的 CI 纪律和代码项目一样:体检可以变快,通道不能绕开。

本节要点回顾

  • CI 是合并的闸门:编译检查加状态选择性构建,只验证改动及其下游,快而不漏。
  • 数据部署分两拍:代码发布分钟级,数据生效随下次构建,验证通过才算闭环。
  • 回滚窗口与排期常识:增量数据用回拨水位修复,高风险变更避开周末前发布。
  • 最简流水线五件事:触发器、凭据注入、体检三步、结果回帖、幂等发布。
  • CI 移交的是合并权:人的判断留给逻辑对错,机器负责标准与可复现。

代码能安全到达生产了,最后一环是日常运转:谁按什么节奏跑、出了事谁先知道。下一节讲调度与监控。


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