1.2 核心架构组成:Core、适配器与 Cloud


1.2 核心架构组成:Core、适配器与 Cloud

本节摘要:dbt 的机体由三部分组成:Core 是本地的编译器与执行器,负责把模板 SQL 变成可执行语句并驱动仓库干活;适配器是连接不同数仓的翻译层,让同一套项目代码能跑在几十种平台上;Cloud 是托管版,把调度、环境、文档与权限搬到了网页里。理解三者的分工,你就能明白「一条命令背后发生了什么」,也能在选型时判断免费版够不够用。

先看三块部件各管什么

把 dbt 比作一台施工设备,三个部件的分工可以这样记:Core 是发动机,适配器是不同工地的转接头,Cloud 是带调度的中央控制室。

Core 是开源的命令行程序,装在本地或你的服务器上。所有核心命令——编译、运行、测试、生成文档——都是它发出的。它读入你的项目文件(模型、配置、测试、宏),在本地完成编译,把产物 SQL 通过数据库连接发给仓库执行,再把结果与日志汇报给你。它自己不存任何数据,也不带调度能力:你让它跑它才跑,什么时候跑由 cron、Airflow 或者 dbt Cloud 决定。

适配器(adapter) 解决的是「仓库方言不一致」的问题。Snowflake、BigQuery、Redshift、PostgreSQL、Databricks,各家仓库的 SQL 方言、连接方式、权限模型都不一样。dbt 的做法是把「生成 SQL、管理依赖、跑测试」这些通用逻辑留在 Core,把「怎么连接、怎么建表建视图、怎么处理事务」这些平台相关的逻辑抽到适配器里。装哪个适配器,dbt 就会说哪家的「方言」。这套设计和数据库驱动、浏览器内核的适配器模式一脉相承:上层协议统一,底层实现各异。

dbt Cloud 是官方的托管平台,把开发者要在自己机器上搭的一整套东西搬到了网页:网页里的开发编辑器、定时调度、环境管理、执行历史、文档托管、权限与审计。Core 加自建调度可以搭出功能等价的组合,代价是自己维护;Cloud 用订阅费换运维成本。两者的项目代码完全兼容——用 Core 开发的项目可以直接放上 Cloud,反过来也一样。

一条命令的完整旅程

以最常用的构建命令为例,从敲下回车到数据落库,中间经过这几步:

  1. 读取项目配置:找到项目根目录的工程配置文件,确定模型目录、物化默认值、目标环境等参数;
  2. 读取连接配置:确定这次连哪个仓库、用哪个账号(这套配置通常放在项目之外,不进版本库);
  3. 解析依赖图:扫描所有模型文件,把每个模型引用的上游收集起来,构建 DAG,并用拓扑排序算出可并行的执行批次;
  4. 编译:把带模板语法的 SQL 渲染成各仓库可执行的纯 SQL,引用函数替换成目标表名;
  5. 执行:按依赖顺序把 SQL 发给仓库,同一批次内的模型并行跑;
  6. 汇报:输出每个模型的结果、耗时与错误信息,退出码标记整体成败。

这套流程里,1、2 属于装配,3、4 属于 Core 的编译期,5 属于执行期,6 是观测。后面章节的很多机制都落在这几步上:物化策略影响第 5 步的执行方式,宏可以介入第 4 步的编译过程,性能调优主要优化第 3、5 步。

图:Core 与适配器的协作关系

适配器模式的实际意义:一次编写,多处运行

讲一个能体现这套架构价值的场景。某公司把分析仓库从自建 PostgreSQL 迁到云上的 BigQuery,数据团队担心几十个模型全部重写。实际情况是:模型的 SQL 主体(SELECT 语句)基本原样迁移,需要调整的只有三类零碎之处——个别方言函数(日期截断函数两家写法不同)、物化配置(把为 PostgreSQL 调的参数换成 BigQuery 的分区与聚簇配置)、以及连接配置里的项目与数据集参数。三天内完成迁移,期间旧环境还并行跑了一周做数字比对。

之所以能这么轻,是因为「这个模型依赖哪些上游、按什么顺序跑、测试怎么验」这些信息全都存在项目代码里,与具体仓库无关;换仓库换的只是适配器这层「转接头」。反过来,这个案例也有另一面:适配器屏蔽了连接与物化的差异,但屏蔽不了算力与成本模型差异。 同样一条 SQL,在 PostgreSQL 上全表扫无所谓,在 BigQuery 上可能就是一笔可观的扫描费用。迁平台时真正要重新设计的,是每个大模型的分区、聚簇与物化策略——这也是第四章性能调优要展开的内容。

选型时三块部件怎么取舍,给你一个工程上的经验判断:个人学习与小型团队,Core 加免费的调度手段完全够用,不产生任何订阅费用;中型团队一旦出现「多环境管理混乱、执行历史查不到、文档没人更新」三类症状中的两类,Cloud 的费用通常比自建运维的人力便宜;已重仓某朵云数仓的团队,也可以考察该仓库官方的数据平台是否已内置 dbt 集成,避免多维护一套调度。

⚠️ 常见坑:连接配置(仓库地址、账号、密钥)绝对不要写进项目仓库。它包含凭据,且随环境而变——本地开发、持续集成、生产调度各有一份,由环境变量或部署流程分别注入。把凭据提交进版本库是 dbt 项目里最常见也最严重的安全事故,第六章安全一节还会回到这个话题。

部署形态的三个常见问题

Core 装在哪、怎么装

Core 是标准的命令行程序,用 Python 包管理器安装,装完即得一组命令。对新手友好的是:安装不依赖任何数据库——没有仓库也能编译项目,只是不能执行。学习路径可以完全离线起步:装 Core、初始化示例项目、跑编译命令看产物,等真的要跑数据时再申请仓库账号。这个「先编译后连接」的离线可能性,也解释了为什么 CI 流水线的编译检查不需要仓库凭据以外的资源。

一个团队里要不要统一 Core 版本

要。依赖解析与编译行为在版本之间存在细节差异,两个同事用不同版本,可能出现「我这编译通过、你那报错」的幽灵问题。工程做法是把版本号钉在项目的依赖声明文件里,配合一个锁文件机制保证全团队安装到同一版本——思路与 4.2 节「包版本钉死」完全一致:所有影响构建行为的输入都要可复现。

适配器装多个会有冲突吗

不会冲突,但建议按需精简。适配器只是额外的 Python 包,装多少个互不干扰,连接配置里用「目标」区分走哪个适配器。真正的取舍是维护面:项目声明了五个适配器,等于五行「这些平台都是我们的支持范围」,每次方言差异排查都要考虑五个变量。多数项目的现实是主力仓库一家、偶尔加一家做迁移——声明你真在用的,卸掉你只是「可能会用」的。

本节要点回顾

  • 三块部件一个比喻:Core 是发动机(编译与执行),适配器是转接头(方言翻译),Cloud 是带调度的中央控制室(托管协作)。
  • 一条命令六步:读工程配置、读连接配置、解析依赖图、编译、执行、汇报——机制章与调优章的内容全部挂在这几步上。
  • 适配器模式的价值与限度:换仓库时模型代码基本通用,但分区、聚簇与成本模型仍需按平台重新设计。
  • 凭据不进仓库:连接配置随环境注入,这是安全底线,不是最佳实践建议。

下一节我们换个视角:把 dbt 和它要替代的老办法放在同一张桌子上比一比,看依赖、测试、文档、复用四个维度上,三种方案各得几分。


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