跳转至

Ch 52 架构师的复盘:取舍、遗憾与主流对比

面包屑

本书主页Part VIII 治理与复盘 › Ch 52

项目第 4 年末 · 持续演进——回头看,向前走


本章你将学到

  • 当时做对的事:配置驱动/同构仓/事件驱动/工程诚实
  • 当时的遗憾:止步 Parquet/单线程调度/无主动血缘/始祖仓治理债
  • 与主流方案的系统性对比
  • 如果重来:下一代数据平台的十个设计原则

这是全书的最后一章,也是我心里最拧巴的一章。

拧巴不是因为没话写——是因为"诚实"这两个字,真要下笔是需要勇气的。写"做对了什么"不难,谁不喜欢讲自己的高光时刻。但写"做错了什么""遗憾了什么"就完全是另一回事了,这等于承认:如果我当初想得更清楚、能力更强,有些坑就不会踩进去。

但我觉得,一本书要只讲成功不讲失败,它没有真正的价值。读者从成功里学到的东西,远不如从失败里学到的多。

所以这一章,我把四年里"做对了"和"遗憾的"都放上来,然后回答那一个绕不开的问题:如果今天重来,我会怎么建这个平台?

在回答这个问题之前,让我们先沿着项目时间线回顾一下这四年:

%%{init: {'theme':'base','themeVariables':{'primaryColor':'#edf5ff','primaryTextColor':'#161616','primaryBorderColor':'#0f62fe','lineColor':'#697077','secondaryColor':'#d9fbfb','tertiaryColor':'#f2f4f8'}}}%%
timeline
 title 四年回顾:从孤岛到智能
 section 做对的
 第0年 : 五层模型 / 配置驱动
 第1年 : 同构仓库 / 事件驱动
 第2年 : 10TB迁移 / 双桶同步
 第3年 : RLS/CLS治理 / 工程诚实
 第4年 : Agentic BI / 语义平面
 section 遗憾的
 第0年 : 止步Parquet / 始祖仓
 第1年 : 单线程DAG / 无主动血缘
 第2年 : truncate+COPY非原子
 第3年 : 数据可观测缺失
 第4年 : YAML编写成本高
 section 如果重来
 未来 : Iceberg / OpenLineage
 未来 : 按域拆仓 / 有界并发
 未来 : 原子加载 / 语义层原生
 未来 : 数据项目永远在生长

图 52-1 本章你将学到


52.1 当时做对的事

%%{init: {'theme':'base','themeVariables':{'primaryColor':'#edf5ff','primaryTextColor':'#161616','primaryBorderColor':'#0f62fe','lineColor':'#697077','secondaryColor':'#d9fbfb','tertiaryColor':'#f2f4f8','fontSize':'14px'}}}%%
flowchart TB
 subgraph 做对的事["四个做对的设计决策"]
 R1[ 配置驱动架构<br/>加数据源=加配置,零代码]
 R2@{ icon: "codicon:person", form: "rounded", label:  同构仓库模式<br/>CI 复用/模板复制/人员轮岗, pos: "b", h: 36 }
 R3@{ icon: "logos:aws-step-functions", form: "rounded", label:  事件驱动编排<br/>Step Functions + S3 事件<br/>即时触发, pos: "b", h: 40 }
 R4[ 工程诚实<br/>文档化已知边界<br/>诚实面对 trade-off]
 end
classDef bpSuccess fill:#defbe6,stroke:#198038,stroke-width:2px,color:#161616
class R1,R2,R3,R4 bpSuccess
linkStyle default stroke:#697077,stroke-width:2px

图 52-2 当时做对的事

做对的事 价值 为什么对
配置驱动 新增数据源从"改代码"变为"加配置" 开闭原则在数据工程的落地
同构仓库 一套 CI 服务所有业务域 规模化时的可维护性
事件驱动 数据到达即触发,无需轮询 时效性 + Serverless 的天然匹配
工程诚实 已知边界文档化,使用者知道避坑 信任建立 + 排障加速

表 52-1 当时做对的事


52.2 当时的遗憾

%%{init: {'theme':'base','themeVariables':{'primaryColor':'#edf5ff','primaryTextColor':'#161616','primaryBorderColor':'#0f62fe','lineColor':'#697077','secondaryColor':'#d9fbfb','tertiaryColor':'#f2f4f8','fontSize':'14px'}}}%%
flowchart TB
 subgraph 遗憾["四个遗憾"]
 L1[ 止步 Parquet 无表格式<br/>无 ACID/Time Travel/Upsert]
 L2[ 单线程 DAG 调度<br/>大规模任务并行度不足]
 L3[ 无主动血缘<br/>审计日志是被动血缘<br/>无法自动影响分析]
 L4[ 始祖仓治理债<br/>新旧标准混合<br/>长期维护两套]
 end
classDef bpError fill:#fff1f1,stroke:#da1e28,stroke-width:2px,color:#161616
class L1,L2,L3,L4 bpError
linkStyle default stroke:#697077,stroke-width:2px

图 52-3 当时的遗憾

遗憾 当时约束 如果重来
止步 Parquet Iceberg/Delta 早期,China 支持有限 直接用 Iceberg,获得 ACID/Time Travel/Upsert
单线程 DAG 最简单可靠 有界并发(max_workers),平衡速度与安全
无主动血缘 审计日志"够用" 从第一天集成 OpenLineage,事后补血缘难十倍
始祖仓治理债 快速上线,全部放一个仓 从第一天按业务域拆仓,哪怕初期只有 2-3 个任务

表 52-2 当时的遗憾

这四个遗憾不光是"当时没做"——每个背后都有实打实的后续成本。把遗憾量化了,后来者才能掂量清楚"这些选择为什么值得在第一天就做对":

遗憾 后续补救成本 说明
止步 Parquet ~6 人月 后期补 Upsert/Time Travel 需迁移到 Iceberg,改 ETL 逻辑 + 全量重写历史分区
单线程 DAG 大表迁移多耗 ~30% 时间 跨账号同步场景,单线程串行执行,有界并发可省近三分之一耗时
无主动血缘 ~2 人周/季度 DSR 响应、排障、影响分析都需人工拼血缘,事后补血缘比一开始收集难十倍
始祖仓治理债 ~1 人月/季度 新旧两套标准并存,每次变更都要兼容旧仓,长期维护负担累积

表 52-3 当时的遗憾

引申

把这些遗憾搬到秤上一称,结论很清楚:四个"当时省的力气",后续付出的成本远远超过了"第一天就做对"的成本。止步 Parquet 省下初期大概 1 人月的 Iceberg 适配工作量,后头换来 6 人月的迁移改造——典型的小账精算、大账糊涂。这也是"工程诚实"的价值所在:量化遗憾不是为了自虐,是让后来人看清哪些所谓"捷径"其实走不通。

引申

这些遗憾有一个共同的味道:短期省力,长期还债。技术债跟金融债其实一个道理——借的时候舒服(快速上线),还的时候肉疼(长期维护两套标准、事后补血缘、单线程瓶颈)。架构师该做的,是在"上市速度"和"技术债"之间做有意识的选择,而不是稀里糊涂地滚雪球。


52.3 与主流方案的系统性对比

%%{init: {'theme':'base','themeVariables':{'primaryColor':'#edf5ff','primaryTextColor':'#161616','primaryBorderColor':'#0f62fe','lineColor':'#697077','secondaryColor':'#d9fbfb','tertiaryColor':'#f2f4f8','fontSize':'14px'}}}%%
flowchart TB
 subgraph 四类方案["四类企业数据平台方案"]
 A[A 方案:AWS 自组装<br/>本书]
 B[B 方案:Snowflake-first<br/>云原生一体化]
 C[C 方案:Databricks Lakehouse<br/>湖仓一体]
 D[D 方案:dbt+Airflow<br/>开源组装]
 end
classDef bpProcess fill:#edf5ff,stroke:#0f62fe,stroke-width:2px,color:#161616
class A,B,C,D bpProcess
linkStyle default stroke:#697077,stroke-width:2px

图 52-4 与主流方案的系统性对比

维度 A: AWS 自组装 B: Snowflake-first C: Databricks Lakehouse D: dbt+Airflow
数据仓库 Redshift Snowflake Databricks SQL 任意(PG/BigQuery/Snowflake)
数据湖 S3+Parquet 内置 S3+Delta/Iceberg S3+任意
ETL Glue Snowpipe/Task Databricks Spark dbt + 任意执行器
编排 Step Functions Snowflake Task/Airflow Databricks Workflows Airflow
IaC Terraform Terraform Terraform Terraform
运维负担 中低
锁定程度 中高
中国可用(现在)
适合场景 AWS 深度用户 追求托管 湖仓一体需求 忌讳锁定

表 52-4 与主流方案的系统性对比

选型建议

%%{init: {'theme':'base','themeVariables':{'primaryColor':'#edf5ff','primaryTextColor':'#161616','primaryBorderColor':'#0f62fe','lineColor':'#697077','secondaryColor':'#d9fbfb','tertiaryColor':'#f2f4f8','fontSize':'14px'}}}%%
flowchart TD
 Q1{团队规模与运维能力?}
 Q1 -->|小团队/低运维|Q2{接受锁定?}
 Q1 -->|大团队/高运维|Q3{湖仓一体需求?}

 Q2 -->|是|B[Snowflake-first<br/>托管省心]
 Q2 -->|否|D[dbt+Airflow<br/>开源可控]

 Q3 -->|是|C[Databricks Lakehouse<br/>湖仓原生]
 Q3 -->|否|A[AWS 自组装<br/>灵活可控]
classDef bpDecision fill:#fcf4d6,stroke:#f1c21b,stroke-width:2px,color:#161616
classDef bpProcess fill:#edf5ff,stroke:#0f62fe,stroke-width:2px,color:#161616
class Q1,Q2,Q3 bpDecision
class A,B,C,D bpProcess
linkStyle default stroke:#697077,stroke-width:2px

图 52-5 选型建议

Trade-off

没有"最佳方案",只有"最适合的方案"。四年前我们选 A(AWS 自组装)是因为 Snowflake/Databricks 未入华。今天如果重新选,对于追求托管体验的团队,B(Snowflake)可能更优;对于湖仓一体需求,C(Databricks)更优。关键是"有意识地选择",而非"默认继承"。


52.4 如果重来:下一代数据平台的十个设计原则

%%{init: {'theme':'base','themeVariables':{'primaryColor':'#edf5ff','primaryTextColor':'#161616','primaryBorderColor':'#0f62fe','lineColor':'#697077','secondaryColor':'#d9fbfb','tertiaryColor':'#f2f4f8','fontSize':'14px'}}}%%
flowchart TB
 subgraph 十原则["下一代数据平台十个设计原则"]
 P1[1. 表格式优先<br/>Iceberg/Delta 从第一天用]
 P2[2. 主动血缘<br/>OpenLineage 从第一天集成]
 P3[3. 按域拆仓<br/>从第一天按业务域拆分]
 P4[4. 有界并发<br/>DAG 调度器支持并行]
 P5[5. 原子加载<br/>Staging+RENAME 替代 truncate+COPY]
 P6[6. 语义层原生<br/>数据平台内置语义层<br/>为 AI 消费预备]
 P7[7. 可观测优先<br/>数据可观测平台从第一天引入]
 P8[8. 配置驱动<br/>保持——这是做对的事]
 P9[9. 同构仓库<br/>保持——这是做对的事]
 P10[10. 工程诚实<br/>保持——已知边界文档化]
 end
classDef bpProcess fill:#edf5ff,stroke:#0f62fe,stroke-width:2px,color:#161616
class P1,P2,P3,P4,P5,P6,P7,P8,P9,P10 bpProcess
linkStyle default stroke:#697077,stroke-width:2px

图 52-6 如果重来:下一代数据平台的十个设计原则

原则 来源 说明
1. 表格式优先 遗憾①修正 Iceberg/Delta 获得 ACID/Time Travel
2. 主动血缘 遗憾③修正 OpenLineage 从第一天集成
3. 按域拆仓 遗憾④修正 不再有始祖仓治理债
4. 有界并发 遗憾②修正 DAG 支持并行
5. 原子加载 Ch 34 边界①修正 Staging+REPLACE
6. 语义层原生 AI 转型经验 数据平台为 AI 预备语义层
7. 可观测优先 Ch 49 引申 数据可观测从第一天引入
8. 配置驱动 做对的事 保持
9. 同构仓库 做对的事 保持
10. 工程诚实 做对的事 保持

表 52-5 如果重来:下一代数据平台的十个设计原则

引申

这十个原则中,7 个是"修正遗憾",3 个是"保持做对的"。这反映了架构演进的规律——好的设计需要保持,不好的设计需要修正,而分辨两者的能力,就是架构师的核心价值。这本书的全部内容,归根结底就是在传递这种"分辨与取舍"的能力。

如果今天重建:12 个月落地计划

十个原则不是空谈——如果今天从零重建,下面是把这些原则落地的 12 个月计划,每季度聚焦一个主题,前后季度有依赖关系:

%%{init: {'theme':'base','themeVariables':{'taskColor':'#edf5ff','taskBkgColor':'#edf5ff','taskBorderColor':'#0f62fe','taskTextColor':'#161616','gridColor':'#dde1e6'}}}%%
gantt
 title 如果今天重建的 12 个月计划
 dateFormat YYYY-MM
 axisFormat %Y-Q%q
 section Q1 基础
 表格式优先 Iceberg + OpenLineage 血缘基础 :q1, 2026-01, 3M
 section Q2 架构
 按域拆仓 + DAG 有界并发 :q2, after q1, 3M
 section Q3 数据
 原子加载 Staging+REPLACE + 语义层原生 :q3, after q2, 3M
 section Q4 治理
 可观测优先 + AI 预备 :q4, after q3, 3M

图 52-7 如果今天重建:12 个月落地计划

季度 主题 关键交付 对应原则
Q1 基础 表格式 + 血统 Iceberg 表格式落地 + OpenLineage 集成(哪怕只记 INPUT/OUTPUT) 原则 1(Iceberg)、2(主动血缘)
Q2 架构 拆仓 + 并发 按业务域拆仓(3-5 个)+ DAG 有界并发(max_workers=4) 原则 3(按域拆仓)、4(有界并发)
Q3 数据 原子加载 + 语义层 Staging+REPLACE 原子加载 + 语义资产 YAML 基础 原则 5(原子加载)、6(语义层原生)
Q4 治理 可观测 + AI 预备 数据可观测(新鲜度/质量/基线告警)+ 语义层接入 AI 原则 7(可观测优先)

表 52-6 如果今天重建:12 个月落地计划

Trade-off

12 个月计划的前提是"有足够团队和预算从零重建"。现实中的迁移往往是"边跑边改"——旧平台不能停,新能力逐步注入。这种"共存迁移"比"推倒重建"慢但风险低。本书平台的实际演进更接近"共存迁移"——四年里逐步补了血缘、拆了仓、加了语义层,而非一次推倒重来。12 个月计划是"理想路径",现实是"在约束下逼近理想"。


本章小结

  • 做对的四件事:配置驱动 / 同构仓库 / 事件驱动 / 工程诚实——保持
  • 遗憾的四件事:止步 Parquet / 单线程 DAG / 无主动血缘 / 始祖仓治理债——修正
  • 四类主流方案对比:AWS 自组装 / Snowflake-first / Databricks Lakehouse / dbt+Airflow——无最佳只有最适合
  • 十个设计原则:7 个修正遗憾 + 3 个保持做对——架构师的核心价值是"分辨与取舍"

附录

附录 A 术语表与学习地图 —— 全书正文到此结束,附录提供术语表、索引、技术栈速查与参考文献。

评论