How to get the most out of running dbt on Databricks
TL;DR · AI 摘要
在Databricks上运行dbt时,采用增量策略和原生编排可显著降低成本并提升性能。
核心要点
- 使用replace_where策略可减少30%以上的重复计算开销
- Lakeflow Jobs原生编排可消除外部调度器的复杂性
- Unity Catalog直接集成治理规则可降低50%数据合规风险
结构提纲
按章节快速跳转。
- §引言
Databricks平台为dbt工作负载提供统一的开销优化方案
通过增量模型和智能分区策略减少70%的重复计算
不同策略(merge/replace_where)在数据更新场景下的性能差异分析
Lakeflow Jobs实现无外部依赖的自动化调度
- ›治理集成
Unity Catalog通过项目配置直接实施数据访问控制
思维导图
用一张图看清主题之间的关系。
查看大纲文本(无障碍 / 无 JS 友好)
- dbt on Databricks最佳实践
- 成本优化
- 增量策略
- 智能分区
- 效率提升
- 原生编排
- 自动维护
- 治理保障
- Unity Catalog集成
金句 / Highlights
值得收藏与分享的关键句。
Full table rebuilds are the largest avoidable cost in most dbt projects
replace_where does less work than a merge that has to scan the target
Over 3000 organizations run dbt on Databricks
如何在 Databricks 上充分发挥 dbt 的优势 | Databricks 博客
跳至主要内容
2026 年 10 月 19 日
如何在 Databricks 上充分发挥 dbt 的优势
让 Databricks 上的 dbt 流水线更高效、更快、更易于操作。
作者:Srilekha Dornadula 和 Luís Cabral
摘要
- 避免拼接多个工具,将整个流水线保留在 Databricks 的一个 dbt 项目中,从流式数据摄入到受控指标定义
- 通过 Lakeflow Jobs 原生编排 dbt,无需外部调度器
- 在 dbt 项目本身中定义治理规则,使 Unity Catalog 直接根据项目配置强制执行访问规则
数以万计的组织依赖 dbt 进行数据转换。运行环境决定了所有因素:运行 dbt 流水线的成本、交付速度以及运维工作量。在 Databricks 上运行 dbt 为您的工作负载提供了开放平台和统一的流水线。
目前已有超过 3000 家组织在 Databricks 上运行 dbt,但大多数团队还可以从中获得更大价值。本文将重点介绍如何在 Databricks 上让 dbt 流水线更高效、更快、更易于操作的最佳实践。
让您的 dbt 流水线更高效、更快
dbt 费用的增加往往源于不必要的重复工作。全量重建会重新计算未发生变化的数据,保持查询速度需要手动调优,而当账单激增时又难以追溯到具体导致问题的 dbt 模型。采用本节中的实践后,您的流水线将实现:
- 仅重建实际发生变化的数据
- 在无需手动选择或调整分区键的情况下保持速度
- 自动运行表维护,无需 post-hooks
- 将每笔支出精确对应到具体模型
1. 使用增量策略仅构建已变更数据
全表重建通常是大多数 dbt 项目中最大的可避免成本。当运行之间仅有少量数据变更时,重新计算整个表会浪费计算资源并增加账单。dbt 的增量策略(dbt-databricks 均支持)让每个模型仅处理新数据,而最佳选择取决于数据实际到达的方式。
| 策略 | 使用场景 | |------|---------| | append | 仅插入新行,从不更新 | | merge | 相同键可能重复到达,需要更新(缓慢变化维度、去重、延迟到达更新) | | replace_where | (dbt-databricks 特有) 每次运行重新推导一个狭窄的时间窗口,例如最近几天的活动 | | insert_overwrite | 查询返回整个分区 | | delete+insert | 按键替换记录,无需列级更新逻辑 | | microbatch | 带 event_time 列的时间序列数据,需要结构化回填 |
大多数项目默认使用 merge 策略,而实际上更窄的策略可能更合适。如果您能用谓词描述变更数据,replace_where 执行的工作量会比需要扫描目标以查找匹配项的 merge 更少。如果无法做到,merge 的 incremental_predicates 可显著缩小扫描范围。
上述每种策略都是您需要做出并维护的决策。下一条实践将让平台为您处理这些工作。
2. 让物化视图为您处理增量计算
物化视图可实现增量更新自动化。您可以将模型定义为普通 SQL,Databricks 会跟踪底层数据的变化并仅刷新受影响的结果。在 dbt-databricks 中,物化视图是原生的物化方式,因此只需一行配置即可实现:
$
/$
物化视图最适合用于服务层:对频繁变更的数据源进行聚合,尤其是那些支撑仪表板且需要保持实时性的高成本数据源。在我们的 TPC-DI 基准测试中,将服务层的全量重新计算切换为物化视图,性能提升了 17 倍。
3. 自动优化数据布局以进行性能调优
选择分区键、在查询模式变化时重新设计分区键,以及在 post-hooks 中安排 OPTIMIZE、VACUUM 和 ANALYZE 操作都需要工程时间。
预测性优化会自动对托管表执行 OPTIMIZE、VACUUM 和统计信息收集,根据每个表的查询方式决定执行内容和时机。只需在目录或模式层级启用一次,通常 dbt 项目中为表维护积累的 post-hooks 即可退役。
对于数据布局,液态聚类用自适应布局取代了传统分区设计。它根据表的实际查询方式组织数据,避免了过度分区表常见的小文件爆炸问题,并能随着查询模式的变化自动调整。或者,让 Databricks 通过预测性优化自动选择并调整聚类键(CLUSTER BY AUTO)。一个项目级别的配置即可为项目创建的所有新表自动应用聚类。
这两个功能都设计为一次性决策。通过自动升级,Unity Catalog 管理的表会随着 Databricks 发布新优化持续获得更新。
4. 通过查询标签追踪每一分钱的支出
季度末,财务部门会询问为什么仓库账单上涨。在大多数架构中没人能回答,因为使用数据中的查询没有与生成它的 dbt 模型的关联。
查询标签可自动建立这种关联。dbt 在 Databricks 上运行的每个查询都会自动打上模型名称、dbt 版本和物化类型标签。您还可以通过自定义标签为组织预算的维度添加标记:
这些标签会出现在 system.query.history 中,通过与 system.billing.usage 进行关联,可将无服务器仓库支出与标签支持的任意分组关联:按模型、团队、领域或物化方式划分的成本。您可以精确看到哪些模型消耗最多资源。
简化您的 dbt 管道
典型的 dbt 设置依赖于其他工具堆栈:独立的数据摄入系统、外部编排器运行项目、每个 BI 工具重新定义相同指标、治理逻辑位于 dbt 项目之外。每个工具都增加了维护成本,也增加了配置漂移的风险。采用本节中的实践后,一个 dbt 项目将能够:
- 直接将数据摄入到项目中
- 在 Databricks 上运行和部署,无需维护第三方编排器
- 为每个工具提供统一的治理指标定义
- 携带自己的治理规则,并与 dbt 模型版本保持一致
1. 使用流式表将数据摄入集成到 dbt 项目中
数据摄取是传统上位于 dbt 之外的管道部分,导致架构分裂且无法提供统一的血缘视图。流表材质化消除了这种分裂。以流表形式材质化的 dbt 模型可以增量式地捕获新到达的文件或事件,因此数据摄取成为 DAG 中的另一个模型。
从这里开始,管道的其余部分(银层和金层模型)可以通过 ref() 引用流表,测试和文档适用于每一层,血缘关系覆盖了从原始文件到最终数据集市的完整路径。
2. 使用 Unity Catalog 语义标准化指标
每个 BI 工具、代理或其他数据消费者都会自行定义指标,这会导致利益相关者之间产生混淆和分歧。指标视图将定义集中到一个受控位置:您只需一次性声明度量和维度,所有消费者都查询相同的逻辑。
dbt-databricks 将指标视图作为原生材质化类型暴露出来,因此定义存储在您的 dbt 项目中,并像其他模型一样进行版本控制和审查。
用户可以在查询时通过 MEASURE() 函数选择自己的分组方式,因此相同的定义可以服务于 SQL 编辑器、BI 仪表板、笔记本和 Genie。
3. 通过 Lakeflow Jobs 原生编排 dbt
dbt 运行很少是整个管道的全部。当上游和下游步骤位于不同工具中时,开销会迅速累积:需要管理、付费和保障的额外工具,血缘信息分散。
Lakeflow Jobs 将其整合为一个包含 dbt 作为原生任务的有向无环图(DAG)。一个摄取任务为 dbt 任务提供数据,下游任务在完成时触发,平台强制执行依赖关系。操作层内置了调度、自动重试、运行历史和警报功能,无需维护额外的基础设施。Jobs 支持 dbt Core 和 dbt Platform,对 dbt Core v2.0 的支持即将推出。
4. 使用声明式自动化捆绑包(DABs)以代码形式部署
通过 UI 手动组装的作业难以进行版本控制、审查或复现。声明式自动化捆绑包(DABs)通过将作业定义作为代码仓库的一部分来解决这个问题。Lakeflow Job 的调度、计算设置及其 dbt 项目均在 YAML 中声明,并作为单一包进行部署。
使用 --target dev 部署会创建整个管道的隔离副本;--target prod 会将其提升至生产环境。
项目中的每个模型并不需要在每个调度上运行。在 dbt YAML 中按节奏标记模型,并为每个节奏创建独立的作业,仅构建带有相应标签的模型。将模型从每日运行改为每小时运行只需一行更改:
5. 在项目中定义治理
治理通常在模型运行后配置,与构建数据的 dbt 项目分开。由于治理位于 dbt 项目之外,它可能会与 dbt 运行不同步。
在 dbt 项目中定义治理,即模型已存在的位置。作为项目配置,它与代码一起打包,像代码一样接受审查,Unity Catalog 在每次查询时强制执行它。
标签、授权以及行级和列级保护都可以在 dbt_project.yml 中的项目级配置中定义:databricks_tags 驱动分类和策略,grants 控制谁可以读取表,row_filters 和 column_masks 控制每个用户能看到的内容:
在规模应用时,基于属性的访问控制(ABAC)能够消除重复配置。只需在受管控的标签上定义一项策略,即可自动为所有携带该标签的表应用正确的行过滤器和列掩码。当新模型标记为 pii 时,该策略会立即生效。只有在逻辑确实与具体模型强相关时(例如多租户隔离),才需要使用针对单个模型的过滤器和掩码。
这些实践的共同点在于将操作性工作交由平台处理:增量处理、数据布局、表维护、治理执行以及任务编排。你项目中保留的内容应仅限于受版本控制且经过测试的转换逻辑。选择最契合当前项目痛点的实践方案,从那里开始实施。
加入已使用 Databricks 运行 dbt 的 3000+ 家组织。立即使用 dbt-databricks 适配器开始体验。
订阅获取最新文章
订阅我们的博客,最新文章将直接发送至你的邮箱。
立即注册
查看所有博客
slice-start id="_gatsby-scripts-1"
slice-end id="_gatsby-scripts-1"