数据工程

本质

数据工程维护组织的派生数据状态:每个数据产物都是源数据、变换逻辑与时间共同决定的结果,并成为下游的输入。源数据不受控、逻辑持续变化、错误被持久化并沿依赖传播,三者使派生状态天然趋向不可信;数据工程的机制都在回答同一个问题——如何让派生状态可约束、可验证、可重建。

数据工程是构建与维护数据系统和流程的工程学科:将来自不受控源系统的原始数据,持续转化为可信、一致、可被下游使用的信息。

组织持续用数的能力是数据工程的长期产出,该产出同时依赖数据治理提供的所有权、标准与制度。

派生状态模型

任一数据产物可表示为:

$$ D^{(t)} = f_{v}\left(S^{(\le t)},\ D_{\text{up}}^{(t)}\right) $$

符号 含义 工程属性
$S^{(\le t)}$ 截至时刻 $t$ 的源数据 由源系统按其业务目标产生,数据团队无控制权
$f_{v}$ 版本为 $v$ 的变换逻辑 随口径变更、缺陷修复持续演化,且可能追溯生效
$D_{\text{up}}^{(t)}$ 上游派生产物 产物被持久化并复用,依赖关系构成 DAG
$t$ 时间 事件时间与处理时间分离,迟到数据使"某时刻的状态"需要显式定义

与在线服务的根本差异在于错误的形态:服务的错误多为瞬时的,修复代码即止损;派生状态的错误是持久的,修复代码之后还须修复已产出的状态及其全部下游。"修代码不等于修数据"是数据工程难以直接套用软件交付实践的原因。

约束、失效与机制

根本约束 不处理时的失效形态 工程回应 机制要点 事实源
输入不受控:源系统对下游没有义务,其 schema 是未经约定的接口 schema 漂移与语义静默变化,下游在结构校验通过的情况下产出错误结果 约束输入 将隐式依赖转为显式接口;接口按生产级用途建立,由消费需求驱动 数据集成、数据建模
错误持久且传播:运行成功不蕴含数据正确,错误产物成为下游输入 扩散面随依赖深度放大,发现越晚修复越贵 验证输出 对数据本身做断言,以消费方可见的交付单元定义可靠性目标;陈旧优于错误,异常时阻断而非继续产出 数据质量、数据运维
逻辑随时间变化:口径变更、缺陷修复、迟到数据要求改写历史 历史结果不可解释,重算结果与原结果不一致,修复引入新错误 重建状态 可复现 = 不可变输入 + 版本化逻辑 + 确定性变换;重跑必须安全(结果幂等),而非被禁止 数据处理、数据建模

三项机制相互依赖:没有验证,无从知道何时需要重建;没有可重建能力,验证发现的问题只能靠人工修补;没有输入约束,验证与重建会被源端变更持续消耗。

价值目标:三种成本

派生状态模型回答"凭什么成立",价值目标回答"优化什么":

持续、低成本地将数据转化为可被组织使用的确定性价值

这一目标拆解为三种成本:

  1. **流动成本**(系统到系统):数据从产生到可用的代价
  2. **理解成本**(人到数据):使用者正确理解并信任数据的代价
  3. **协作成本**(人到人):生产者、加工者与消费者之间对齐的代价

可信的派生状态是三种成本优化的前提,而不是与之并列的另一个目标:状态不可信时,流动越快错误扩散越快,越容易理解则误用越广,协作越密则单点错误的影响面越大——降本努力会放大损失。

机制 \ 成本 流动 理解 协作
约束输入 主:减少源端变更引发的修复与重跑 次:字段语义随接口固定 主:生产者与消费者的义务显式化
验证输出 次:异常前置拦截,减少返工 主:可信度可观察,使用者无需自行核验 次:问题定位有共同证据
重建状态 主:故障修复与口径变更的代价可控 主:历史结果可按逻辑版本解释 次:变更不再需要全员协调停机

适用边界

五层职责模型

分层把变化节奏与控制权不同的部分隔离开,由层间接口吸收变化;派生状态的三项机制沿这些接口落位。

分层隔离变化的通用原理与完整逻辑分层见数据架构。本节只回答数据工程的增量问题:每层的变化由谁控制、在哪里被吸收、三项机制由哪一层承担。

五层与变化来源

层 核心问题 主要变化来源 控制权 对应数据架构分层
价值层 数据如何产生业务影响 业务策略与用例 业务方;是数据工程的需求来源,不属于其职责 —
服务层 数据如何被安全、稳定地消费 消费方与访问模式 与消费方共同约定 数据服务层
处理层 数据如何被变换与建模 业务口径 数据团队;口径决策权归治理 语义层
集成层 数据如何进入系统 源系统 schema 与接口 不受控 接入与传输层
基础设施层 存储与计算如何稳定运行 存储计算形态、计算引擎、云平台 数据团队或平台团队 存储层、计算层

层间接口:变化在哪里被吸收

边界 隔离的变化 接口形态 接口被绕过时
源系统 → 集成层 源端 schema 与语义变更 源端接口约定,或防御性摄取 源端变更直达模型,下游静默出错
集成层 → 处理层 原始格式与业务语义的差异 不可变的原始数据层 摄取时混入业务逻辑,口径变更需要重新摄取
处理层 → 基础设施层 计算引擎与存储换代 SQL、开放表格式等标准接口 口径用引擎专有接口实现,换引擎等于重写口径
处理层 → 服务层 内部模型重构 稳定的数据服务出口 消费方直接读内部表,内部重构即破坏下游

"接口被绕过时"一列可用作诊断信号:出现即说明分层只停留在命名上。

三项机制的分层落位

机制 集成层 处理层 服务层 基础设施层
约束输入 主:源端边 辅:语义随版本冻结 主:消费边 —
验证输出 辅:入口检测结构漂移 主:单元级与模型级断言 主:按交付单元的端到端验证 —
重建状态 主:原始数据持久保留 主:版本化逻辑与结果幂等 — 前提:廉价的不可变存储与可重放计算

三项机制都跨越多层,但每层承担的部分不同,且都依赖上一节的接口:接口缺失的层,对应机制无处落地。

代价与边界

生命周期:状态的修正与终结

五层模型描述职责在空间上的划分,生命周期描述一份派生状态在时间上的轨迹:它被产出后仍要被修正,最终要被终结;这两段轨迹决定了派生状态的长期可信度与成本。

三段轨迹

生成 → 流动 → 沉淀 → 建模 → 服务 → 反馈修正(回流上游)→ 退役

段 阶段 派生状态的变化 划分依据
产出 生成、流动、沉淀、建模、服务 源数据进入系统,逐级派生为可消费的产物 建模与其他变换分开:语义建模承担口径一致性,变化节奏慢于变换实现,对应五层模型中"口径归处理层、引擎归基础设施层"
修正 反馈修正 已产出的状态被重算或更正 派生状态的错误是持久的,产出之后必须存在一条回到上游的修正路径
终结 退役 原始数据被删除,派生产物被下线 只增不减时,存储、计算与验证成本持续累积;合规删除也要求明确的终点

反馈修正:错误如何被纠正

修正是一条与数据流方向相反的路径,每一步依赖不同的前置能力:

步骤 动作 依赖 失效形态
发现 识别产出偏离预期 验证输出;消费方反馈渠道 由消费方先发现,错误已被用于决策
定位 沿依赖回溯根因所在的产物与逻辑版本 数据血缘;运行记录 依赖人工排查,修复对象找错
修正 修复源端数据或变换逻辑 版本化逻辑 覆盖旧逻辑,历史结果无法按原口径解释
重建 重算受影响的分区及其全部下游 不可变输入、结果幂等;血缘给出影响面 只修根节点,下游仍保留错误结果;或重跑造成重复
通知 告知消费方受影响范围与更正时间 消费边接口;交付单元定义 消费方不知数据已变,系统内外结果不一致

退役:状态如何终结

对象 触发 派生状态特有的约束
原始数据 保留期届满;合规删除请求 删除须沿依赖传播到所有派生产物,否则数据在下游残留;删除范围内不再可重建
派生产物 消费方消失或长期无访问;维护与验证成本超过其价值 下线前确认无下游依赖,经消费边通知并给出迁移期;直接删除会破坏未登记的消费方

机制展开

约束只说明派生状态为何不可信,三项机制也只给出应对方向;本章展开每项机制成立所依赖的条件、条件被破坏时的失效形态以及投入的取舍。这些条件不随工具更替而改变,可直接用于评估新工具和定位故障。

约束输入:依赖边上的接口

派生状态的每条依赖边都是一个接口:上游产物是下游的输入,约束输入的机制因此适用于 DAG 的每一条边。两类边的风险最高:

依赖边 接口失控的形态 机制 事实源
源端边:源系统 → 数据平台 直接读取生产库 schema,源系统按业务需要修改结构与语义,下游静默出错 由消费需求驱动的源端接口约定,变更前感知影响面 数据集成
消费边:数据平台 → 外部消费方 消费方直接依赖内部表,内部重构即破坏下游 数据服务:以稳定出口隔离内部实现 数据中台

接口由三个要素构成,缺一则约束失效:

适用边界:接口约束只对生产级用途建立。探索期数据的价值未经验证,提前约束会把研发成本转嫁给尚不存在的消费方。仅由生产方定义的接口常因生产方不了解下游用途而失效,接口内容应由消费需求驱动、由生产方维护。

验证输出:对数据本身断言

任务运行成功只证明代码执行完毕,不证明数据正确;验证必须作用于产出的数据,而非执行过程。验证按范围分三级,每级只能捕获特定类别的错误:

范围 捕获 漏检
单元级:单个变换 逻辑缺陷 输入漂移、跨阶段的字段假设
模型级:单个产物 粒度、主键、口径约束被破坏 上下游语义不一致
端到端:从源到消费 跨阶段的隐含假设失配、交付延迟 定位困难,需血缘辅助

各阶段分别达标不蕴含端到端正确,可靠性目标因此以消费方可见的交付单元(如某一时间分区的产物)定义。失败按形态处置:

投入按关键产物与用例分级,不追求全量覆盖。质量维度定义见数据质量,监控与告警体系见数据运维,SLO 的通用概念见可观测性。

重建状态:让重跑安全

口径变更、缺陷修复、迟到数据都要求改写已产出的历史,重建能力决定这些修正的代价。可重建依赖四个条件:

条件 含义 破坏时的后果
不可变输入 原始数据落地后持久保留、不被改写 修正后无法回到原始事实重算
版本化逻辑 口径变更视为逻辑新版本,按生效期区分新旧口径,而非覆盖旧逻辑 重算历史时误用新口径
确定性变换 相同输入与逻辑产出相同结果 重算结果与原结果不可比
结果幂等 产出以分区为单位整体覆盖,重复执行结果相同 重跑导致重复计数或残留状态

结果幂等与执行去重是两个概念:执行去重阻止任务重复运行,结果幂等保证重复运行无害;重建依赖后者。

代价与边界:

机制取舍:采用与降级信号

三项机制的投入随"下游扩散面 × 错误代价"变化,任一机制都存在不值得全量投入的场景:

机制 采用信号 降级信号 降级后的替代
约束输入 产物进入生产级用途;源端变更已引发事故;同一产物有多个消费方 探索期;生产方与唯一消费方同属一个团队;源系统为不可协商的第三方 防御性摄取:入口处检测结构漂移并隔离异常批次
验证输出 产物服务外部消费方或决策;错误被发现的时间晚于被使用的时间 告警长期无人处置或以误报为主;断言维护成本超过其拦截的损失 收缩为少量端到端关键断言加异常检测;阻断降为告警
重建状态 口径会追溯变更;存在迟到数据;历史结果用于对外披露或审计 变换不确定;全量快照的存储成本超过返工成本;合规要求删除原始数据 以可追溯代替可复现:保留逻辑版本与运行记录,修正以更正记录表达而非改写历史

降级是对投入强度的调整,不是放弃对应约束:约束依然存在,只是由代价更低的方式承受其后果。

演进:机制的成熟路径

组织规模、协作复杂度与数据使用密度共同推高产物的"下游扩散面 × 错误代价";当它超过实现某项机制的成本时,该机制从缺位转为必需,构成阶段迁移的动力。

阶段 识别信号 机制状态 优先投入 过早投入的代价
项目驱动 需求逐个交付;口径散落在应用层;问题由消费方发现 三项机制缺位,靠人工修补 原始数据持久保留;核心产物的端到端验证 需求未稳定时建平台或全量接口约束,规范被绕过
规模化 同一指标多处实现、结果不一;修复依赖个人 机制靠规范与评审执行 口径收敛;高扩散产物的接口约束;重跑安全 规范缺少工具卡点,执行成本随人数线性增长
平台化 规范执行成本过高;同类管道重复实现相同机制 三项机制成为平台默认能力 接口登记、通用断言、安全重跑下沉为平台行为 平台先于共识,错误抽象被固化
联邦化 中心团队成为交付瓶颈 领域团队自持产物与接口,平台提供机制,中心制定标准 领域所有权与统一标准 领域团队尚无维护能力时下放,质量责任悬空

阶段划分是对多个组织案例的归纳,规模较小或直接采用托管服务的团队可能跳过中间阶段。平台化与联邦化的具体形态见数据中台与数据网格。

关联内容(自动生成)