返回

在Databricks上高效运行dbt的实践指南

RSS Databricks Blog AI 逐段翻译 发布 2026-10-20 03:45

有效阅读仅保存在当前浏览器,用于「为你」推荐;暂停或清除记录。

DataHot 速览

Databricks 官方博客介绍如何在 Databricks 上更高效地运行 dbt。文章称已有超过3000家组织在 Databricks 上运行 dbt,但多数团队仍有优化空间。文中给出增量策略选择(append、merge、replace_where、insert_overwrite、delete+insert、microbatch)、自动表维护和按模型归因成本等实践。目标是让 dbt 管道更便宜、更快、更易运维。

为什么值得关注:对使用 dbt + Databricks 的数据团队有直接参考价值,涵盖增量策略、表维护和成本归因等可落地的性能与成本优化方法。

本文目录 11 节
  1. 让你的 dbt 管道更便宜、更快速
  2. 1. 使用增量策略只构建发生变化的部分
  3. 2. 让物化视图为你处理增量计算
  4. 3. 自动化数据布局以进行性能调优
  5. 4. 使用查询标签归因每一美元支出
  6. 简化你的 dbt 管道
  7. 1. 使用流式表将数据摄取纳入 dbt 项目
  8. 2. 使用 Unity Catalog Semantics 标准化指标
  9. 3. 通过 Lakeflow Jobs 原生编排 dbt
  10. 4. 使用 Declarative Automation Bundles 以代码形式部署
  11. 5. 在项目中定义治理

译文

AI 逐段翻译

数万个组织依赖 dbt 进行数据转换。你在哪里运行它决定了方方面面:运行 dbt 管道的成本、交付速度,以及所承载的运维工作量。在 Databricks 上运行 dbt 能为你的 dbt 工作负载提供一个开放平台和统一管道。

超过 3000 个组织在 Databricks 上运行 dbt,而大多数团队本可以从中获得更多收益。本文重点介绍能让 dbt 管道在 Databricks 上更便宜、更快速、更易于运维的实践。

让你的 dbt 管道更便宜、更快速

dbt 账单的攀升源于你无需重复的工作。全量重建会重新计算未发生变化的数据,保持查询快速需要手动调优,而当账单激增时,又无法清晰地归因到导致问题的 dbt 模型。采用本节中的实践后,你的管道将:

  • 只重建实际发生变化的数据
  • 无需你选择或重做分区键即可保持快速
  • 无需 post-hooks 即可自动运行表维护
  • 将每一美元支出追踪到具体模型

1. 使用增量策略只构建发生变化的部分

全表重建是大多数 dbt 项目中最大的可避免成本。当两次运行之间只有一小部分数据发生变化时,重新计算整张表会浪费你的计算资源并增加账单。dbt 的增量策略均在 dbt-databricks 上受支持,可让每个模型只处理新数据,而正确的选择取决于你的数据实际如何到达。

策略适用场景
append行只会被插入,从不更新
merge同一个键可能多次到达且需要更新插入(缓慢变化维度、去重、延迟到达的更新)
replace_where(dbt-databricks 专有)模型在每次运行时重新推导一个狭窄的时间窗口,例如最近几天的活动
insert_overwrite你的查询返回完整分区
delete+insert(dbt-databricks 专有)你想按键替换记录,但不涉及列级更新逻辑
microbatch具有 event_time 列且需要结构化回填的时间序列数据

大多数项目默认使用 merge,即使更狭窄的策略就足够了。如果你能用谓词描述变化的数据,replace_where 所做的工作比需要扫描目标表以查找匹配项的 merge 更少。如果你无法做到,在 incremental_predicates 中为 merge 设置增量谓词可以大幅缩小该扫描范围。

上述每种策略都是你需要做出并维护的决定。下一项实践让平台为你处理这件事。

2. 让物化视图为你处理增量计算

物化视图 可自动完成增量计算。你可以用普通 SQL 定义模型,Databricks 会跟踪哪些底层数据发生了变化,并仅刷新受影响的结果。在 dbt-databricks 上,物化视图是一种原生物化,因此这只是一行配置的改动:

物化视图最适合服务层:对频繁变化的源进行聚合,尤其是那些支撑仪表板且需要保持新鲜的昂贵聚合。在我们的 TPC-DI 基准测试中,将服务层的全量重算切换为物化视图带来了 17 倍的加速。

柱状图显示服务层的物化视图带来了 17 倍加速

3. 自动化数据布局以进行性能调优

选择分区键、在查询模式变化时重做它们,以及在 post-hooks 中调度 OPTIMIZE、VACUUM 和 ANALYZE,都会占用工程时间。

预测性优化 会在托管表上自动运行 OPTIMIZE、VACUUM 和统计信息收集,并根据每张表的查询方式选择运行什么以及何时运行。在目录或 schema 级别启用一次,dbt 项目通常为表维护积累的 post-hooks 就可以退役了。

对于数据布局,Liquid Clustering 用自调优布局取代了分区设计。它根据表的实际查询方式组织数据,避开了过度分区表所遭遇的小文件爆炸问题,并随查询模式的变化而自适应。或者借助由预测性优化驱动的 自动 Liquid Clustering(CLUSTER BY AUTO),让 Databricks 根据查询历史选择并调整它们。一个项目级配置即可为项目构建的每张新表设置聚类。

这两项功能都被设计为一次性决策。借助 自动升级,Unity Catalog 托管表会随着 Databricks 发布新优化而持续获得这些优化。

4. 使用查询标签归因每一美元支出

季度末,财务部门会问为什么数据仓库账单上涨了。在大多数配置中,没有人能回答,因为使用数据中的查询与发出它的 dbt 模型之间没有任何关联。

查询标签 让这种关联自动建立。dbt 在 Databricks 上运行的每个查询都会自动打上模型名称、dbt 版本和物化类型。添加你自己的 DIY 自定义标签,用于组织预算所依据的维度:

这些标签会出现在 system.query.history 中,与 system.billing.usage 进行连接,即可将无服务器仓库支出归因到标签支持的任何分组:按模型、按团队、按领域、按物化类型的成本。你可以确切看到哪些模型成本最高。

简化你的 dbt 管道

典型的 dbt 设置依赖一堆其他工具:一个单独的系统用于摄取数据,一个外部编排器用于运行项目,每个 BI 工具都会重新定义相同的指标,以及治理规则位于 dbt 项目之外。每一样都是额外需要维护的东西,也是额外可能发生漂移的地方。采用本节中的实践后,一个 dbt 项目将能够:

  • 直接将数据摄取到项目中
  • 从 Databricks 运行和部署,无需维护第三方编排器
  • 向每个工具提供统一的受治理指标定义
  • 自带治理规则,并与你的 dbt 模型一起进行版本控制

1. 使用流式表将数据摄取纳入 dbt 项目

摄取是管道中传统上位于 dbt 之外的部分,导致架构割裂且没有统一的血缘概览。streaming_table 物化消除了这种拆分。以流式表物化的 dbt 模型会随着新文件或事件到达而增量地获取它们,因此数据接入就变成了 DAG 中又一个普通的模型。

从那里开始,管道的其余部分(silver 和 gold 模型)可以用 ref() 来引用这个流式表,测试和文档适用于每一层,血缘覆盖了从原始文件到最终 mart 的整条路径。

2. 使用 Unity Catalog Semantics 标准化指标

每个 BI 工具、智能体或其他数据消费者都会构建自己的指标定义,这会导致利益相关者之间产生困惑和分歧。一个 指标视图 将定义移入一个受治理的统一位置:你只需声明一次度量和维度,每个消费者都会查询相同的逻辑。

dbt-databricks 将 指标视图 暴露为一种原生物化类型,因此定义就存放在你的 dbt 项目中,像任何其他模型一样被版本化并接受审查。

用户可以在查询时使用 MEASURE() 函数自行选择分组,因此同一份定义便可服务于 SQL 编辑器、BI 仪表板、笔记本和 Genie。

3. 通过 Lakeflow Jobs 原生编排 dbt

dbt 运行很少就是整条管道。当上游和下游步骤位于不同工具中时,额外开销会不断累积:需要额外管理、付费和保障安全的工具,以及分散的血缘。

Lakeflow Jobs 将其整合为一个有向无环图(DAG),并将 dbt 作为原生任务。数据接入任务为 dbt 任务提供输入,下游任务在其完成后触发,依赖关系由平台强制执行。运维层已内置调度、自动重试、运行历史和告警,无需维护任何额外基础设施。Jobs 支持 dbt Core 和 dbt Platform,对 dbt Core v2.0 的支持也即将推出。

4. 使用 Declarative Automation Bundles 以代码形式部署

在 UI 中手工组装的任务难以版本化、审查或复现。 Declarative Automation Bundles(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 的新模型在构建的那一刻就受到覆盖。只有当逻辑确实是模型特有的时候(例如多租户隔离),才需要为单个模型设置过滤器和掩码。

这些实践的共同主题是将运维工作交给平台:增量处理、数据布局、表维护、治理执行和编排。留在你的 dbt 项目中的是经过版本控制和测试的转换逻辑。选择能解决你项目当前痛点的实践,并从那里开始。

加入已在 Databricks 上运行 dbt 的 3000+ 组织。从 dbt-databricks 适配器 开始使用。

这篇内容对你有用吗?

反馈只用于改善内容筛选,不等同于收藏

分享这条资讯
分享海报
保存图片
iOS 也可以长按图片保存