谈到数据架构,人们很容易想到数据仓库、数据湖、湖仓一体、Lambda架构、Kappa架构或数据网格。
这些模式当然属于数据架构的讨论范围,但《数据工程之道》第3章真正想说明的,不是哪种模式最好,而是一个更基础的问题:
当业务需求、数据规模和技术环境不断变化时,系统怎样以可接受的成本持续演进?
作者将数据架构定义为:
支持企业不断变化的数据需求,并通过谨慎权衡形成灵活、可逆决策的系统设计。
这个定义把架构的重点从"系统现在长什么样",转向"系统未来怎样变化"。
总说
从第一性原理看,企业建设数据系统是为了持续支持业务目标,而业务和技术都不会保持不变。
因此,架构的核心任务不是预测一个完美终局,而是:
- 从业务目标推导系统需要具备的能力;
- 通过松耦合和可逆决策降低变化成本;
- 提前设计故障、扩展、安全和成本边界;
- 将大规模变更拆成小而可验证的演进步骤。
书中的九项原则可以归纳为三类:
text
管理变化
+ 控制复杂度
+ 约束风险
它们共同回答:
系统如何在需求变化、故障发生和规模增长时,仍然保持可调整、可恢复和可负担?
一、架构的本质是管理变化
1. 为什么"当前能运行"不能证明架构合理
一个系统今天能够运行,只能证明当前方案满足了当前需求。
但数据系统面对的对象始终在变化:
- 业务指标会调整;
- 数据来源会增加;
- 上游schema会演进;
- 消费时效会提高;
- 数据规模会增长;
- 安全和合规要求会变化;
- 当前使用的技术也可能被替代。
因此,评价架构不能只看今天是否可用,还要看变化发生后需要付出多大代价。
如果修改一个特征公式,需要同时修改数据表、调度任务、模型代码和下游接口,那么系统虽然可以运行,但变化成本已经非常高。
相反,如果特征通过稳定契约发布,研究定义、计算实现和模型消费彼此隔离,那么内部实现变化就不必同时影响所有下游。
所以,架构质量可以从变化成本理解:
text
变化影响范围越大
→ 决策越难撤销
→ 系统越容易僵化
→ 长期架构风险越高
2. 可逆决策为什么重要
书中使用"单向门"和"双向门"说明架构决策的差异。
单向门是难以撤销的决策。例如,所有数据、逻辑和运行流程都绑定在一个专有平台上。一旦平台不再适合,迁移会同时影响代码、数据、人员和流程。
双向门是容易撤销的决策。例如,模块通过稳定接口交互,内部数据库或计算引擎可以替换,下游不需要跟随修改。
作者强调可逆决策,是因为未来无法被准确预测。
如果多数决策都能撤销,团队就可以:
- 更快尝试;
- 用真实结果验证假设;
- 根据新信息调整方向;
- 避免一次性押注远期方案。
因此,好架构不是把未来全部设计出来,而是让团队在未来到来时仍然有调整空间。
3. 架构需要区分"做什么"和"怎样做"
书中将数据架构分为运行架构和技术架构。
运行架构回答:
- 数据服务什么业务流程;
- 质量要求是什么;
- 数据多久需要可用;
- 失败造成什么影响;
- 谁负责;
- 系统需要什么恢复能力。
技术架构回答:
- 数据怎样获取;
- 保存在哪里;
- 使用什么计算方式;
- 如何编排任务;
- 如何发布和监控。
正确的推导顺序是:
text
业务目标
→ 运行要求
→ 质量属性
→ 技术架构
例如,金融模型需要在每天20点前获得可信特征,这是运行要求。
使用日批获取行情、版本化保存原始数据,并通过候选区和质量门禁发布特征,则是满足该要求的技术方案。
如果直接从Kafka、Dagster或某个特征平台开始,就把"怎样做"放在了"为什么做"之前。
二、好架构需要处理三类问题
《数据工程之道》提出九项架构原则:
- 明智选择通用组件;
- 为失败做计划;
- 为可扩展性设计;
- 架构是领导力;
- 持续进行架构设计;
- 构建松耦合系统;
- 做出可逆决策;
- 优先考虑安全;
- 拥抱FinOps。
逐项记忆容易显得零散。它们可以归纳为三类架构责任。
1. 管理变化:让架构能够持续演进
这一类包括:
- 做出可逆决策;
- 持续进行架构设计;
- 通过架构领导力推动演进。
作者认为,架构不是项目启动时完成的一张图,而是持续变化的过程:
text
识别当前状态
→ 定义目标状态
→ 将变化拆成小步骤
→ 验证每一步结果
→ 根据新信息调整目标
目标架构不是固定终点,而是随业务和技术环境不断调整的方向。
架构领导力也不是命令所有团队使用同一种技术。
优秀的架构师既要作出关键技术判断,也要向团队传播判断方法、通用原则和实践经验,使团队能够独立解决更复杂的问题。
如果所有决策都依赖架构师亲自拍板,架构师本身就会成为组织瓶颈。
因此,架构领导力的价值不是集中更多决定,而是提高整个团队作出正确决定的能力。
2. 控制复杂度:让组件和团队能够独立变化
这一类包括:
- 明智选择通用组件;
- 构建松耦合系统;
- 为失败和扩展进行设计。
通用组件解决的是重复建设问题。
版本控制、对象存储、编排、监控和可观测能力,如果每个团队都自行建设,不仅浪费资源,还会形成彼此不兼容的孤岛。
但作者同样反对"一刀切"。通用组件应服务于普遍需求,却不能为了统一而阻止具体领域采用更合适的方案。
松耦合则解决变化传播问题。
松耦合系统通常具备三个特点:
- 系统被拆成职责明确的组件;
- 组件通过稳定接口或消息契约交互;
- 一个组件的内部变化不要求其他组件同步修改。
它带来的直接结果是:
text
内部实现变化
→ 被稳定接口隔离
→ 下游不必同时修改
→ 团队能够独立测试和发布
松耦合不仅是技术设计,也是团队协作方式。团队通过明确的接口、所有权和服务承诺协作,而不是直接依赖对方的内部数据库和实现细节。
为失败设计
书中强调,任何组件经过足够长的时间都会失败。因此,失败不应被看成意外,而应被看成正常架构条件。
架构设计需要提前明确:
- 可用性;
- 可靠性;
- RTO,即最长可接受恢复时间;
- RPO,即最多可以丢失多少数据。
例如,内部研究报告可以接受一天后恢复,但实盘交易特征可能只能接受几分钟延迟。
不同业务后果,应推导出不同的恢复机制,不能对所有系统使用同一套高可用标准。
为实际规模扩展
可扩展性不仅意味着能够扩大,也意味着负载下降后能够缩小,甚至缩到零。
但作者同样提醒,没有真实负载依据的扩展设计,会产生不必要的复杂度和成本。
正确顺序是:
text
测量当前负载
→ 估计峰值和增长
→ 判断现有方案是否足够
→ 必要时再引入扩展机制
"未来可能增长"不能自动成为提前建设复杂分布式系统的理由。
3. 约束风险:让系统安全且可负担
这一类包括:
- 安全优先;
- FinOps;
- 对可靠性、性能和成本持续权衡。
安全必须进入初始设计
书中强调零信任和责任共担。
云平台可以保证基础设施层面的安全,但用户仍然要对数据权限、网络配置、密钥管理和访问方式负责。
因此,安全不是系统建成后的补充功能,而是每位数据工程师都需要承担的设计责任。
架构需要提前回答:
- 谁可以访问哪些数据;
- 服务之间怎样认证;
- 敏感数据怎样隔离;
- 访问是否留下审计记录;
- 某个凭证泄露后的影响范围有多大。
成本也是架构反馈
FinOps要求工程、业务和财务共同管理技术支出。
在云环境中,资源可以随时扩展,但每次查询、计算、存储和数据传输都可能产生动态成本。
因此,架构不能只追求更快和更稳定,还要持续观察:
- 单位数据处理成本;
- 每个数据产品的计算成本;
- 空闲资源;
- 重复存储和重复计算;
- 成本增长是否产生对应业务价值。
好架构不存在所有维度同时最优的状态。
它始终是在以下因素之间作出权衡:
text
业务价值
灵活性
可靠性
性能
安全
成本
复杂度
架构师的工作不是消灭权衡,而是让权衡有依据、可解释,并能在条件变化后重新评估。
三、如何将这些原则应用到金融特征工程
以用于T+1选股的20日动量为例。
如果直接从技术实现出发,团队可能马上讨论:
- 使用什么数据库;
- 是否建设特征平台;
- 是否使用实时流处理;
- 是否引入Dagster;
- 表应该怎样分层。
但按照书中的架构方法,应先定义运行要求。
1. 先确定运行要求
text
业务用途:
用于T日晚间模型评分和T+1组合构建
交付时间:
每天20点前完成可信发布
正确性要求:
不能使用未来数据,行情、复权和股票池版本必须明确
失败要求:
系统性错误阻断;少量股票异常允许降级
恢复要求:
失败后在约定时间内重新计算和发布
复现要求:
历史模型运行能够还原当时使用的特征版本
这些要求不依赖具体技术,却决定了后续架构。
2. 用松耦合降低变化影响
系统可以划分为三个主要责任:
text
研究定义
→ 特征生产与发布
→ 模型消费
三者通过特征契约衔接。
研究员可以修改公式,但必须升级特征版本;数据工程可以替换计算引擎,但不能改变研究语义;模型只依赖发布契约,不直接依赖内部表结构。
因此,某个模块变化时,不必要求整条链路同时修改。
Dagster在这里负责依赖和运行协调,例如等待行情到齐、触发计算和执行发布流程,但不负责定义20日动量的公式。
这就是"业务逻辑不进入编排器"的来源:它不是一句孤立规范,而是松耦合和责任分离在当前项目中的具体推导。
3. 用候选与发布隔离失败
特征计算结果先进入候选区,通过检查后再发布可信版本:
text
行情和复权数据就绪
→ 计算候选特征
→ 检查覆盖率、时点和分布
→ 发布可信版本
→ 模型消费
如果少量股票输入异常,可以隔离后降级发布;如果出现系统性复权错误、日期错位或未来数据,就阻断整个版本。
发布失败时,上一可信版本不会被覆盖。
这对应书中的失败设计,但"候选---可信发布"是结合金融特征场景推导出的具体机制,并不是书中的固定模式。
4. 让重要决策保持可逆
当前需求是日频、日终计算,就没有必要仅因为未来可能实时化,提前建设完整流处理架构。
可以先采用简单批处理完成可信闭环,并明确重新评估条件:
- 特征频率提升到分钟或逐笔;
- 模型开始盘中决策;
- 日批无法在决策窗口内完成;
- 数据量造成持续性能瓶颈。
只要数据契约和模块边界稳定,未来就可以替换获取或计算方式,而不用推翻研究定义和消费接口。
这才是可逆架构,而不是"永远不改变技术"。
5. 将安全和成本纳入同一判断
金融特征涉及行情授权、研究成果和策略信息,因此需要:
- 区分研究、回测和实盘权限;
- 限制原始行情和敏感特征访问;
- 保留发布和读取审计;
- 避免日志泄露模型及策略参数。
同时需要持续观察:
- 每个特征的计算成本;
- 历史回填成本;
- 原始快照保留成本;
- 长期无人使用的特征;
- 重复特征和重复计算。
如果一个特征长期无人使用,却每天消耗大量计算资源,那么即使任务稳定运行,也不能证明架构合理。
四、怎样将书中原则沉淀为项目架构
原先提出的项目原则,需要区分两类。
1. 来自书中的通用架构原则
- 从业务目标和运行要求出发;
- 通过松耦合降低变化成本;
- 优先做出可逆决策;
- 提前设计失败和恢复;
- 根据实际负载扩展;
- 将安全和成本纳入架构。
2. 结合金融场景推导出的项目规则
- 研究定义、数据生产和模型消费责任分离;
- 业务逻辑不进入编排器;
- 模型只能读取可信发布版本;
- 原始来源证据不能被静默覆盖;
- 先完成日频纵向闭环,再评估实时化;
- 特征、数据和模型运行必须通过版本关联。
这些项目规则不是书中可以直接复制的结论,而是使用书中的判断方法,对当前业务目标、失败代价和变化风险进行分析后得到的架构决策。
因此,每项关键决策都应留下记录:
text
它解决什么业务问题
→ 影响哪些质量属性
→ 为什么选择当前方案
→ 放弃了什么
→ 决策是否容易撤销
→ 出现什么条件需要重新评估
例如,"一期采用日批而不使用流处理"不能只写成技术结论。
完整记录应说明:
- 当前模型只在日终运行;
- 日批能够满足20点交付要求;
- 流处理不会产生额外交易行动价值;
- 实时系统会增加状态、恢复和运维成本;
- 模块通过稳定接口交互,未来仍可替换为流式获取;
- 当模型转向盘中决策时重新评估。
这样,技术决策才有业务依据、权衡过程和演进条件。
结语
《数据工程之道》第3章真正值得吸收的,不是九项原则,也不是数据仓库、数据湖或数据网格等模式。
它提供的是一套面对变化作出架构决策的方法:
text
识别当前业务问题
→ 定义运行要求和质量属性
→ 评估价值、风险与成本
→ 优先选择松耦合和可逆方案
→ 为失败、安全和扩展留出边界
→ 将变化拆成小步持续验证
好架构不是一个看起来先进的终局,而是一套能够持续应对变化的机制。
它既能满足今天的业务目标,也不会因为一次技术选择,把系统锁死在今天。