dbt 支持 Amazon Redshift 数据共享读写
DataHot 速览
dbt 官方宣布原生支持 Amazon Redshift 数据共享的读与写。用户可跨 Redshift 数据仓库物化模型,并在开发与 CI 环境之间隔离,无需复制或移动数据。此次还升级 dbt-redshift,从旧版 Postgres 元数据 API 迁移到 Redshift 原生的 SVV_* 系统视图和 SHOW API。官方称该版本可带来更快运行、更可靠元数据解析和高并发下更好的表现。
为什么值得关注:面向使用 dbt 与 Redshift 的数据团队,说明跨库/跨集群建模、开发与 CI 隔离及数据共享读写的新能力,并涉及元数据 API 迁移带来的性能与可靠性变化。
本文目录 9 节
译文
AI 逐段翻译对于 Amazon Redshift 用户来说,dbt 中最受期待的功能之一终于来了:对 Amazon Redshift 数据共享读写的原生支持。通过此版本,dbt 可以跨 Redshift 数据仓库物化模型,开启一类全新的多团队数据架构——全程无需复制或移动任何一个字节。
除了数据共享支持外,此版本还包含一项重大的底层升级:dbt-redshift 已从旧的 Postgres 元数据 API 迁移到 Redshift 原生的 SVV_* 系统视图和 SHOW API。其结果是 dbt 运行更快、元数据解析更可靠,并在高并发工作负载下表现出显著更好的行为。
让我们深入了解有哪些变化以及为什么这很重要。
什么是 Redshift 数据共享?
Amazon Redshift 数据共享让你能够跨 Redshift 集群、无服务器工作组、AWS 账户和 AWS 区域安全地共享实时数据,而无需复制或移动数据。生产者向一个或多个使用者公开数据库对象(schema、表、视图、物化视图、UDF),使用者可以像访问本地数据一样实时查询这些数据。由于所有使用者都从同一个实时源读取数据,因此一旦生产者的写入被提交,他们始终能看到事务一致的最新信息。
到目前为止,dbt 无法充分利用这一点。模型只能在有限条件下引用外部数据库中的源:RA3 或无服务器节点类型、特殊的 ra3_node: true 配置文件标志,以及一个硬性约束——任何引用数据共享源的模型都必须物化为表。视图不行。跨项目引用不行。跨越集群的高级 CI 环境也不行。
通过此版本,这一切都改变了。
解决方案:datasharing: true
此版本的核心是一个新的配置文件凭据:datasharing: true。
以下是它解决的问题。默认情况下,当你配置一个 dbt 模型写入到连接所指向的数据库之外的另一个数据库时——使用类似 {{ config(database='dev_analytics') }} 的方式——dbt 在写入之前需要对该目标数据库进行内省。它使用 PostgreSQL 目录表(pg_tables、pg_views、information_schema)来完成此操作,而这些表只能显示当前所连接数据库中的对象。如果你的连接指向 dev,而你的模型目标是 dev_analytics,那么这些元数据查询对 dev_analytics 不会返回任何内容,跨数据库写入就会失败,并报出类似以下的错误:
模型 fct_tpch_orders 中的数据库错误
在事务内无法写入不同的数据库,因为事务开始前未设置
USEd 数据库。
设置 datasharing: true 会将适配器的元数据查询切换到 Redshift 原生的 SVV_* 系统视图和 SHOW API,它们具备跨数据库感知能力。启用此标志后,dbt 能够正确解析其未直接连接的数据库的元数据,跨数据库写入便能成功。
在 dbt platform 中,你可以通过环境上的 Extended Attributes 来设置——无需更改代码:
datasharing: true
在本地,它放在你的 profiles.yml 中的 Redshift 连接配置下。
注意:datasharing: true 目前在 dbt platform 的 Latest 发布轨道上处于 Beta 阶段。它在 Compatible 或 Extended 轨道上尚不可用。
端到端设置
设置涉及三个步骤。
步骤 1——创建目标数据库。在你的 Redshift 查询编辑器中,连接到你的主数据库并创建你想要写入的数据库:
CREATE DATABASE dev_analytics;
步骤 2——配置你的模型。将 database='dev_analytics' 添加到模型配置中:
{{
config(
materialized = 'table',
database='dev_analytics'
)
}}
select * from {{ ref('stg_orders') }}
步骤 3——在你的 dbt platform 环境中启用 datasharing。在 dbt platform → Orchestration → Environments → 你的环境 → Extended attributes 中,添加:
datasharing: true
就是这样。dbt 现在将正确解析 dev_analytics 的元数据,并在那里物化模型。
关于权限的一个重要说明:datasharing: true 启用了跨数据库写入所需的元数据路径,但它不会授予数据库权限。你的数据库用户仍然需要目标数据库上的 CREATE 权限。如果权限设置不正确,你会收到权限错误——datasharing: true 只能解决事务上下文问题,不能解决访问控制问题。
Defer 与跨数据库写入:同一个故事的两个章节
使用此功能最强大的方式是与 dbt 的 defer 能力结合使用。这两者结合在一起直接解决了 Redshift 客户的一个常见问题:当你的环境完全隔离在不同的 AWS 账户中时,如何有效地使用 dbt?
第一章是结合 datasharing 的 defer。你的 dev 环境通过 Redshift 数据共享跨账户读取生产环境的表,从而实现精简 CI 和快速迭代,而无需复制生产数据。这不需要任何特殊的适配器标志——只需基础设施设置(AWS Organizations + Redshift 数据共享配置)。
第二章是结合 datasharing: true 的跨数据库写入。你的 dev 环境将模型写入一个单独的目标数据库(如 dev_analytics),而上游引用仍然通过数据共享 defer 到 prod。这两件事在同一次 dbt 运行中同时发生:上游模型跨账户针对生产数据解析,而当前模型物化到 dev 目标数据库中。
这种组合意味着 dev 环境可以真正隔离——独立的集群、独立的数据库、独立的 AWS 账户——同时仍然针对真实的生产数据进行迭代,并且不会与生产工作负载争抢资源。
这为 dbt platform 功能解锁了什么
Redshift 数据共享支持不仅仅修复了一个物化问题。它让一系列原本被阻塞的 dbt platform 功能能够为 Redshift 客户正确工作。
dbt Mesh / 跨项目引用:使用 dbt Mesh 将大型项目拆分为独立负责的领域的团队,现在可以跨不同 Redshift 数据仓库和数据库的项目使用 ref()。下游团队的模型可以依赖上游团队经过认证的数据集,而两个团队都不需要拥有对方正在运行的数据仓库。
高级 CI:dbt 的 CI 环境支持依赖于为每个拉取请求创建精简、隔离的项目版本。借助数据共享支持,CI 环境可以运行在专用集群上,同时通过 datashare 从生产环境读取共享的源数据——从而实现真正隔离、快速的 CI,而无需复制上游数据集。
工作负载隔离:最常见的 Redshift 最佳实践之一是将 ETL 工作负载与 BI 查询流量分离到专用集群上。团队现在可以直接从他们的 dbt 项目配置中将特定模型路由到特定集群或数据库,从而将繁重的转换工作从驱动仪表板的集群上移开——而这一切都无需离开 dbt。
让所有人都更快:元数据 API 升级
即使你没有使用数据共享,此版本也让 dbt-redshift 变得更快。
从 pg_* 目录视图迁移到 Redshift 原生的 SVV_* 系统视图和 SHOW API,不仅是跨数据库可见性所必需的——它同时也显著更快。继承自 Postgres 的旧式元数据视图并非为 Redshift 的架构而设计。在大规模、高并发下,团队看到元数据查询为每次 dbt 运行增加了明显的开销——每次查询数秒,在拥有众多模型的大型项目中成倍放大。
基于 SVV_* 和 SHOW 的 API 针对 Redshift 进行了优化,无论并发或集群规模如何都能返回一致的结果。对于运行大型项目或高线程数的团队来说,改进是显而易见的。
已知限制
Redshift 数据共享是一项强大的能力,但在围绕它进行架构设计之前,有一些值得了解的约束。
在消费者端,你无法直接在数据共享表之上创建常规视图。这是 AWS 层面的限制:在消费者集群上,常规视图不能引用存在于 datashare 中的对象。如果你尝试在 dbt 中构建一个直接查询数据共享源的视图模型,它会失败。
解决方法是先将数据共享的数据物化为表,然后在该表之上构建你的视图。你引用数据共享源的第一层模型应使用 materialized='table' 或 incremental。下游模型则可以像往常一样是视图:
-- 第一层:必须是表,直接从 datashare 读取
{{ config(materialized='table') }}
select * from {{ source('producer_cluster', 'orders') }}
-- 下游:可以是视图,从上面的物化表读取
{{ config(materialized='view') }}
select order_id, customer_id, amount
from {{ ref('stg_orders_from_datashare') }}
where status = 'completed'
延迟绑定视图和物化视图可以从生产者集群共享,但消费者端的常规视图不能直接引用 datashare 对象。请参阅 AWS 关于数据共享中视图支持的文档以了解完整说明。
此外,跨 datashare 的写操作(从消费者集群对生产者表执行 INSERT、UPDATE、DELETE)在 AWS 端有其自身的 SQL 约束。如果你的用例需要双向数据流,请查阅 AWS 关于多仓库写入的文档。
入门
要使用 dbt 的 Redshift 数据共享支持,你需要:
- 一个 RA3 或 RG 或 Redshift Serverless 集群(DC2 不支持数据共享)
- 由你的 AWS 管理员配置的 Redshift datashare
- 在 dbt Cloud(Beta)中位于 Latest 发布轨道的 dbt-redshift,或在本地使用 dbt-redshift v1.11+
- 在你的 profile 或 dbt Cloud Extended Attributes 中设置 datasharing: true
- 连接数据库用户被授予目标数据库的 CREATE 权限
阅读 dbt-redshift 设置文档以获取完整配置参考,并阅读 dbt Cloud 发布说明以了解 Beta 推出的最新信息。
下一步
此版本为 Redshift 上的 dbt 开辟了重要的新领域,我们正在积极跟踪关于下一步构建内容的反馈——包括对跨数据库依赖的更广泛的 IDE 和血缘支持,以及为同时使用 defer 和跨数据库写入的团队扩展 CI/CD 模式。
如果你正在此基础上进行构建并有使用案例——或者遇到了限制——我们希望听到你的声音。在 dbt-adapters 上提交 issue,或在 dbt Community Slack 中发起讨论。
这篇内容对你有用吗?
反馈只用于改善内容筛选,不等同于收藏