基于 Apache Hudi + dbt 构建开放的Lakehouse

简介: 基于 Apache Hudi + dbt 构建开放的Lakehouse

本博客的重点展示如何利用增量数据处理和执行字段级更新来构建一个开放式 Lakehouse。我们很高兴地宣布,用户现在可以使用 Apache Hudi + dbt 来构建开放Lakehouse。

在深入了解细节之前,让我们先澄清一下本博客中使用的一些术语。

什么是 Apache Hudi?

Apache Hudi 为Lakehouse带来了 ACID 事务、记录级更新/删除和变更流。Apache Hudi 是一个开源数据管理框架,用于简化增量数据处理和数据管道开发。该框架更有效地管理数据生命周期等业务需求并提高数据质量。

什么是dbt?

dbt(数据构建工具)是一种数据转换工具,使数据分析师和工程师能够在云数据仓库中转换、测试和记录数据。dbt 使分析工程师能够通过简单地编写select语句来转换其仓库中的数据。dbt 处理将这些select语句转换为表和视图。dbt 在 ELT(提取、加载、转换)过程中执行 T——它不提取或加载数据,但它非常擅长转换已经加载到仓库中的数据。

什么是Lakehouse?

Lakehouse 是一种新的开放式架构,它结合了数据湖和数据仓库的最佳元素。Lakehouses 是通过一种新的系统设计实现的:在开放格式的低成本云存储之上直接实施类似于数据仓库中的事务管理和数据管理功能。如果必须在现代世界中重新设计数据仓库,Lakehouse便是首选,因为现在可以使用廉价且高度可靠的存储(以对象存储的形式)。换句话说,虽然数据湖历来被视为添加到云存储文件夹中的一堆文件,但 Lakehouse 表支持事务、更新、删除,在 Apache Hudi 的情况下,甚至支持索引或更改捕获等类似数据库的功能。

如何建造一个开放的Lakehouse?

现在我们知道什么是Lakehouse了,所以让我们建造一个开放的Lakehouse,你需要几个组件:

• 支持 ACID 事务的开放表格式

• Apache Hudi(与 dbt 集成)

• Delta Lake(锁定到 Databricks 运行时的专有功能)

• Apache Iceberg(目前未与 dbt 集成)

• 数据转换工具

• 开源 dbt 是转换层事实上的流行选择

• 分布式数据处理引擎

• Apache Spark 是计算引擎事实上的流行选择

• 云储存

• 可以选择任何具有成本效益的云存储或 HDFS

• 选择最心仪的查询引擎

构建 Lakehouse需要一种方法来提取数据并将其加载为 Hudi 表格式,然后使用 dbt 就地转换。DBT 通过 dbt-spark 适配器[1]包支持开箱即用的 Hudi。使用 dbt 创建建模数据集时,您可以选择 Hudi 作为表的格式。可以按照此页面[2]上的说明学习如何安装和配置 dbt+hudi。

第 1 步:如何提取和加载原始数据集?

这是构建Lakehouse的第一步,这里有很多选择可以将数据加载到我们的开放Lakehouse中。可以使用 Hudi 的 Delta Streamer工具,因为所有摄取功能都是预先构建的,并在大规模生产中经过实战测试。Hudi 的 DeltaStreamer 在 ELT(提取、加载、转换)过程中执行 EL——它非常擅长提取、加载和可选地转换已经加载到 Lakehouse 中的数据。

第二步:如何用dbt项目配置Hudi?

要将 Hudi 与 dbt 项目一起使用,需要选择文件格式为 Hudi。文件格式配置可以在特定模型中指定,也可以为 dbt_project.yml 文件中的所有模型指定:

models:
   +file_format: hudi

或者

{{ config(
  materialized = 'incremental',
  incremental_strategy = 'merge',
  file_format = 'hudi',
  unique_key = 'id',
) }}

选择 Hudi 作为 file_format 后,可以使用 dbt 创建物化数据集,这提供了 Hudi 表格式独有的额外好处,例如字段级更新/删除。

第三步:如何增量读取原始数据?

在我们学习如何构建增量物化视图之前,让我们快速了解一下,什么是 dbt 中的物化?物化是在 Lakehouse 中持久化 dbt 模型的策略。dbt 中内置了四种类型的物化:

• table

• view

• incremental

• ephemeral

在所有物化类型中,只有增量模型允许 dbt 自上次运行 dbt 以来将记录插入或更新到表中,这释放了 Hudi 的能力,我们将深入了解细节。使用增量模型需要执行以下两个步骤:

• 告诉 dbt 如何过滤增量执行的行

• 定义模型的唯一性约束(使用>= Hudi 0.10.1版本时需要)

如何在增量运行中应用过滤器?

dbt 提供了一个宏 is_incremental(),它对于专门为增量实现定义过滤器非常有用。通常需要过滤“新”行,例如自上次 dbt 运行此模型以来已创建的行。查找此模型最近运行的时间戳的最佳方法是检查目标表中的最新时间戳。dbt 通过使用“{{ this }}”变量可以轻松查询目标表。

{{
   config(
       materialized='incremental',
       file_format='hudi',
   )
}}
select
   *
from raw_app_data.events
{% if is_incremental() %}
   -- this filter will only be applied on an incremental run
   where event_time > (select max(event_time) from {{ this }})
{% endif %}

如何定义唯一性约束?

unique_key 是数据集的主键,它确定记录是否具有新值,是否应该更新/删除或插入。可以在模型顶部的配置块中定义 unique_key。这个 unique_key 将作为 Hudi 表上的主键(hoodie.datasource.write.recordkey.field)。

第 4 步:如何在编写数据集时使用 upsert 功能?

dbt 在加载转换后的数据集时提供了多种加载策略,例如:

• append(默认)

• insert_overwrite(可选)

• merge(可选,仅适用于 Hudi 和 Delta 格式)

默认情况下dbt 使用 append 策略,当在同一有效负载上多次执行 dbt run 命令时,可能会导致重复行。当你选择insert_overwrite策略时,dbt每次运行dbt都会覆盖整个分区或者全表加载,这样会造成不必要的开销,而且非常昂贵。除了所有现有的加载数据的策略外,使用增量物化时还可以使用Hudi独占合并策略。使用合并策略可以对Lakehouse执行字段级更新/删除,这既高效又经济,因此可以获得更新鲜的数据和更快的洞察力。

如何执行字段级更新?

如果使用合并策略并指定了 unique_key,默认情况下dbt 将使用新值完全覆盖匹配的行。由于 Apache Spark 适配器支持合并策略,因此可以选择将列名列表传递给 merge_update_columns 配置。在这种情况下dbt 将仅更新配置指定的列,并保留其他列的先前值。

{{ config(
   materialized = 'incremental',
   incremental_strategy = 'merge',
   file_format = 'hudi',
   unique_key = 'id',
   merge_update_columns = ['msg', 'updated_ts'],
) }}

如何配置额外的Hudi自定义配置?

如果想指定额外的 Hudi 配置时,可以使用选项配置来做到这一点:

{{ config(
   materialized='incremental',
   file_format='hudi',
   incremental_strategy='merge',
   options={
       'type': 'mor',
       'primaryKey': 'id',
       'precombineKey': 'ts',
   },
   unique_key='id',
   partition_by='datestr',
   pre_hook=["set spark.sql.datetime.java8API.enabled=false;"],
  )
}}

总结

希望本篇博文可以助力基于Apache Hudi 与 dbt构建开放的 Lakehouse

目录
相关文章
|
10天前
|
消息中间件 Java Kafka
实时计算 Flink版操作报错合集之从hudi读数据,报错NoSuchMethodError:org.apache.hudi.format.cow.vector.reader.PaequetColumnarRowSplit.getRecord(),该怎么办
在使用实时计算Flink版过程中,可能会遇到各种错误,了解这些错误的原因及解决方法对于高效排错至关重要。针对具体问题,查看Flink的日志是关键,它们通常会提供更详细的错误信息和堆栈跟踪,有助于定位问题。此外,Flink社区文档和官方论坛也是寻求帮助的好去处。以下是一些常见的操作报错及其可能的原因与解决策略。
|
1月前
|
应用服务中间件 网络安全 Apache
构建高性能Web服务器:Nginx vs Apache
【5月更文挑战第16天】Nginx与Apache是两种主流Web服务器,各具优势。Nginx以其轻量级、高并发处理能力和反向代理功能见长,适合大型网站和高并发场景;而Apache以功能丰富、稳定性强闻名,适合企业网站和需要多种Web服务功能的场景。在性能上,Nginx处理高并发更优,Apache则可能在高负载时遭遇瓶颈。在选择时,应根据实际需求权衡。
|
1月前
|
消息中间件 存储 Java
深度探索:使用Apache Kafka构建高效Java消息队列处理系统
【4月更文挑战第17天】本文介绍了在Java环境下使用Apache Kafka进行消息队列处理的方法。Kafka是一个分布式流处理平台,采用发布/订阅模型,支持高效的消息生产和消费。文章详细讲解了Kafka的核心概念,包括主题、生产者和消费者,以及消息的存储和消费流程。此外,还展示了Java代码示例,说明如何创建生产者和消费者。最后,讨论了在高并发场景下的优化策略,如分区、消息压缩和批处理。通过理解和应用这些策略,可以构建高性能的消息系统。
|
1月前
|
存储 SQL 分布式计算
使用Amazon EMR和Apache Hudi在S3上插入,更新,删除数据
使用Amazon EMR和Apache Hudi在S3上插入,更新,删除数据
166 0
|
1月前
|
存储 分布式计算 Hadoop
一文了解Apache Hudi架构、工具和最佳实践
一文了解Apache Hudi架构、工具和最佳实践
274 0
|
1月前
|
SQL 分布式计算 NoSQL
使用Apache Hudi和Debezium构建健壮的CDC管道
使用Apache Hudi和Debezium构建健壮的CDC管道
28 0
|
15天前
|
监控 大数据 Java
使用Apache Flink进行大数据实时流处理
Apache Flink是开源流处理框架,擅长低延迟、高吞吐量实时数据流处理。本文深入解析Flink的核心概念、架构(包括客户端、作业管理器、任务管理器和数据源/接收器)和事件时间、窗口、状态管理等特性。通过实战代码展示Flink在词频统计中的应用,讨论其实战挑战与优化。Flink作为大数据处理的关键组件,将持续影响实时处理领域。
112 5
|
1月前
|
消息中间件 Java Kafka
实时计算 Flink版操作报错之Apache Flink中的SplitFetcher线程在读取数据时遇到了未预期的情况,该怎么解决
在使用实时计算Flink版过程中,可能会遇到各种错误,了解这些错误的原因及解决方法对于高效排错至关重要。针对具体问题,查看Flink的日志是关键,它们通常会提供更详细的错误信息和堆栈跟踪,有助于定位问题。此外,Flink社区文档和官方论坛也是寻求帮助的好去处。以下是一些常见的操作报错及其可能的原因与解决策略。
|
28天前
|
数据处理 Apache 流计算
|
1月前
|
消息中间件 关系型数据库 MySQL
Apache Flink CDC 3.1.0 发布公告
Apache Flink 社区很高兴地宣布发布 Flink CDC 3.1.0!
583 1
Apache Flink CDC 3.1.0 发布公告

推荐镜像

更多