介绍dbt +实现

2021-03-02 04:07:04

管理数据非常困难。管理数据管道更加困难。跨组织转换时,数据仓库中各个表或值的含义会​​丢失。另一个团队的重构破坏了您团队的工作流程。而且,通常很难说出谁进行了更改以及何时进行了更改。

数据构建工具dbt通过接管ETL管道中的转换步骤来减轻这些挫败感。 dbt本身不是数据处理器,而是位于包含已提取和加载的数据的数据仓库的顶部。 dbt使团队可以轻松地测试,记录和版本控制其数据转换。

尽管dbt是转换批处理数据的好工具,但它当前不能实时转换流数据。 (dbt团队在少数情况下明确警告用户。)在Materialize,我们希望帮助世界停止批处理并开始流式传输。因此,我们*构建了一个dbt适配器,该适配器将允许您使用Materialize作为数据仓库实时转换流数据。

本文的其余部分将探讨dbt为什么与批处理数据配合使用效果最佳,以及如何使用Materialize解锁流转换。如果您渴望入门,可以在这里找到dbt-materialize适配器,在这里找到我们的示例流项目。注意:dbt-materialize适配器是一项正在进行中的工作,尚不适用于生产用例。请提出您认为合适的问题或提交PR,我们很乐意提供反馈!

* dbt-materialize适配器最初由Josh Wills创建,并由Jeremy Cohen积极塑造。感谢您的所有工作和支持!

dbt擅长转换批处理数据,但是它不能实时有效地转换流数据。要了解原因,让我们看一下dbt如何在后台转换数据。

dbt用户使用dbt“模型”定义所需的转换。 dbt模型是包含以下内容的SQL文件:

每次“运行”模型时,dbt都会转换您的数据。每次运行模型时,dbt都会使用该模型的SELECT语句查询基础数据仓库。然后将查询的结果集(转换后的数据)直接返回给用户,或者将其持久化到您的数据仓库中,具体取决于模型的实现参数。

当前,dbt支持四种类型的实现:表,视图,增量和临时。表和增量实现将持久化一个表,视图实现将创建一个视图,并且短暂实现而不是持久化任何内容,而是使用通用表表达式(CTE)直接返回结果。好消息是这些数据库对象完全足以转换批处理数据。坏消息是这些数据库对象都没有有效地转换流数据。

首先,批处理和流式传输数据是什么意思?顾名思义,批次数据是离散批次中到达的任何类型的数据。可以是每分钟一次,每小时一次或一天一次。重要的是批次之间没有新数据到达。另一方面,流数据连续到达并且没有特定的时间表。

那么,为什么这些数据库对象足以转换批处理数据,却不能有效转换流数据?

视图和CTE不会物理上将数据保留到您的数据仓库中。这意味着,每次查询使用视图或CTE的模型时,数据仓库都必须重新转换基础源数据。而且,每次转换源数据时,您都要付出一定的代价。虽然视图和CTE总是返回您的批处理和流数据的最新转换,但它们并没有那么高效。

另一方面,表在物理上保留数据。更具体地说,表保留上一次其模型“ dbt运行”的结果集。与视图和CTE不同,这意味着您不必每次查询表时都要付出转换数据的代价。但是,这意味着随着新数据的到来,您转换后的数据很快就会过时。这对于批处理数据不是问题,因为您可以在每次新批处理到达时简单地“ dbt运行”表。不幸的是,流数据并不是那么简单。

由于流数据未按计划到达,因此不再有合适的时间重新运行模型以保持模型最新。相反,您不得不在最大化数据新鲜度和最小化转换成本之间进行选择。通过限制重新创建表的频率,有效地将流数据转换为批处理数据,可以最大程度地降低成本。或者,您可以通过连续重新创建表来最大程度地提高数据的新鲜度。但是,这种方法将花费您的时间和金钱,使您容易受到错误的影响,并且仍然无法保持最新​​的结果。

dbt目前有一种正式和一种非官方的方式来近似转换流数据。这两种方法都无法真正实时地转换流数据,而且都需要付出一定的代价。

近似转换流数据的第一种方法是创建具有增量实现的模型。第一次运行增量模型时,dbt会将转换的结果集持久保存到数据仓库中的表中。对于后续运行,dbt仅转换模型的过滤谓词所指示的源数据的子集。 (例如,您可能有一个过滤谓词,该谓词仅会转换时间戳大于上一个模型运行时间的数据。)

虽然增量模型降低了用户在表中保持转换时面临的权衡的严重性(数据新鲜度与成本),但它们并未完全消除权衡。通过设计,每次“ dbt”运行增量模型时,您可能会付出较少的费用。 (我在这里说“大概”是因为即使每次运行仅转换几行数据,除非您进行了巧妙的过滤,否则模型的SELECT语句仍将必须扫描整个基础源表或视图以发现这些数据行)。尽管这些较低的成本可以使您腾出更多时间运行增量模型,但您仍将无法连续运行它们。根据定义,您仍在使用批处理过程来转换流数据。

近似转换流数据的第二种方法是非官方的“ lambda视图”方法。该方法通过查询组合的历史表和当前视图来模拟“近实时模型”上的转换。与增量实现类似,此方法会产生使用某些过滤器查询两个基础数据库对象的成本。您的数据的当前视图返回最新结果,但是每次都必须重新转换最近的数据。

这些方法都不能实时有效地转换数据。 (而且,如果您有可能迟到的流数据,它们会带来很多麻烦。)为了有效地执行流数据的无忧实时转换,dbt将需要保留一个数据库对象,该对象将更新为新数据到达上游。幸运的是,有一个数据库对象可以为我们做到这一点:物化视图。

传统数据库中的物化视图的行为有点像dbt的增量物化。首次创建实例化视图时,其查询结果集将物理保留在数据库中。然后,以一定间隔或在手动触发时,使用最近的数据更新存储的结果集。像渐增的实现一样,维护这些实现的视图会产生各种成本。

这是实现Materialise所要解决的确切问题。与传统的物化视图不同,我们的物化视图会随着新数据的到达而不断更新-无需刷新。更好的是,我们提供了毫秒级延迟的最新结果。 (有关实体化和我们的实体化视图的更多信息,请查阅我们的文档。)

那么,这对dbt和流数据意味着什么呢? 这意味着您第一次在Materialize之上运行dbt模型时,dbt会保留一个物化视图。 然后,您不必再运行模型。 无论数据到达的频率是多少,模型都将保持最新状态。 无论您何时查询视图,它都将返回新的答案。 只需通过我们的物化视图创建模型,您就可以自信,高效地实时转换流数据。 兴奋的? 怀疑吗? 谨慎乐观? 自己试试吧! 如前所述,我们有一个beta dbt-adapter和一个演示流项目。 如果您有任何想法,问题或疑虑,请随时在我们的Slack社区或dbt仓库中与我们联系。 (或者,当您启动并运行时,实时告诉我们您要进行的转换!)