快捷搜索:  汽车  科技

使用flinkhudi构建流式数据湖:Apache Hudi 新一代流式数据湖平台

使用flinkhudi构建流式数据湖:Apache Hudi 新一代流式数据湖平台我们注意到,Hudi 有时被定位为“表格格式”[12] 或“事务层”。虽然这没有错,但并不能完全体现 Hudi 所提供的一切。数据湖平台今天,能够以增量方式表达几乎任何批处理管道的宏伟愿景比以往任何时候都更容易实现。流处理变得越来越成熟 [3],发展势头也很迅猛 [4],流处理 API 已被推广 [5] 到批处理执行模型上。Hudi 填补了增量处理的空白并提供了高效的面向流式优化的数据湖存储,与 Kafka/Pulsar 为事件流提供高效存储非常类似。数据湖中的流式处理使得许多组织 [6] 能够获取更新鲜的数据、更简化的体系结构和更低的成本。但首先我们需要解决数据湖的基础问题——事务和可变性。在许多方面,Apache Hudi 开创了我们今天所知的事务性数据湖的先河。具体来说,在更多专用系统诞生的时候,Hudi 引入了一个无服务器的事务层,它工作在云存储 /HDFS 的通用 Hadoop

作者 | Vinoth Chandar

译者 | 杨华

审校 | 蔡芳芳

早在 2016 年,我们就提出了一个大胆的新愿景 [1],通过一个新的“增量”数据处理技术栈(结合现有的批处理和流式处理堆栈)重新构想批处理。虽然流处理管道进行面向行的处理,提供秒级处理延迟,但增量管道将对数据湖中的列数据应用相同的原则,高效的数据处理,及相对批处理数量级的改进,同时存储 / 计算可高度扩展。这个新的技术栈将能够毫不费力地支持批量再加工 / 回填的常规处理。Apache Hudi 是作为这一愿景的体现而建立的,它植根于 Uber 面临的真实、困难的问题 [2],后来在开源社区中独树一帜。总之,我们已经能够在数据湖上引入完全增量的数据摄取和中等复杂的 ETL。

使用flinkhudi构建流式数据湖:Apache Hudi 新一代流式数据湖平台(1)

今天,能够以增量方式表达几乎任何批处理管道的宏伟愿景比以往任何时候都更容易实现。流处理变得越来越成熟 [3],发展势头也很迅猛 [4],流处理 API 已被推广 [5] 到批处理执行模型上。Hudi 填补了增量处理的空白并提供了高效的面向流式优化的数据湖存储,与 Kafka/Pulsar 为事件流提供高效存储非常类似。数据湖中的流式处理使得许多组织 [6] 能够获取更新鲜的数据、更简化的体系结构和更低的成本。

但首先我们需要解决数据湖的基础问题——事务和可变性。在许多方面,Apache Hudi 开创了我们今天所知的事务性数据湖的先河。具体来说,在更多专用系统诞生的时候,Hudi 引入了一个无服务器的事务层,它工作在云存储 /HDFS 的通用 Hadoop 文件系统抽象之上。该模型帮助 Hudi 在构建之初就能够将写入器 / 读取器扩展到 1000 个内核,相比之下,传统数仓提供了更丰富的事务保证集,但往往受限于处理它们的 10 多个服务器的规模瓶颈。我们也很高兴看到类似的系统(例如 Delta Lake)后来采用了我们最初在 17 年初共享的无服务器事务层模型 [7]。我们有意识地引入了两种表类型 Copy On Write(具有更简单的可操作性)和 Merge On Read(以获得更大的灵活性),现在这些术语也用于 Hudi 之外的项目 [8],指代从 Hudi 借用的类似想法。通过开源和从 Apache 孵化器毕业 [9] ,我们在将这些想法提升到整个行业 [10] 高度并通过有凝聚力的软件堆栈将它们变为现实方面取得了一些重大进展。鉴于过去一年左右令人兴奋的发展推动了数据湖进一步成为主流,我们认为一些观点可以帮助用户以正确的视角看待 Hudi,了解它代表什么,并成为其发展方向的一部分。此时,我们还想展示 180 多个贡献者 [11] 在该项目上所做的所有伟大工作,他们与 2000 多个独立用户通过 slack/github/jira 合作,贡献了 Hudi 在过去一年获得的所有功能。

这将是一篇相当长的文章,但我们会尽最大努力让它值得你花时间好好品读。来吧。

数据湖平台

我们注意到,Hudi 有时被定位为“表格格式”[12] 或“事务层”。虽然这没有错,但并不能完全体现 Hudi 所提供的一切。

Hudi 是一种“格式”吗?

Hudi 并非设计为通用表格格式,用于跟踪文件 / 文件夹以进行批处理。相反,表格格式提供的功能只是 Hudi 软件堆栈中的一层。鉴于 Hive 格式的广泛流行,Hudi 旨在与 Hive 格式配合得很好。随着时间的推移,为了解决“扩展性”的挑战或引入额外的功能,我们致力于构建自己的原生表格格式,着眼于增量处理的愿景。例如,我们需要支持每隔几秒提交一次的较短事务。我们相信,随着时间的推移,这些要求将完全包含通用表格格式所要解决的挑战。但是,我们也愿意与其他开放表格格式交互,因此其他表格格式的用户也可以从 Hudi 堆栈的其余部分中受益。与文件格式不同,表格格式只是表格元数据的表示,如果用户愿意接受权衡,实际上用户可以从 Hudi 转换为其他格式 / 反之亦然。

Hudi 是一个事务层吗?

当然,Hudi 必须提供事务来实现删除 / 更新,但 Hudi 的事务层是围绕事件日志 [13] 而设计的,该日志也与一整套内置表 / 数据服务很好地集成。例如,压缩知道已经调度的聚簇 (Clustering) 操作并通过跳过正在聚簇 (Clustering) 的文件进行优化 - 而用户幸福地不知道这一切。Hudi 还提供了用于摄取、ETL 数据等开箱即用的工具。我们一直认为 Hudi 是在围绕流处理解决数据库问题——实际上两者是非常相关的领域 [14]。事实上,流处理是由日志(捕获 / 发出事件流、回绕 / 重新处理)和数据库(状态存储、可更新的接收器)启用的。有了 Hudi 这样的框架,如果我们想构建一个支持高效更新和提取数据流的数据库,同时保持针对大批量查询的优化,则可以使用 Hudi 表作为状态存储和可更新接收器来构建增量管道。

因此,将 Apache Hudi 描述为围绕数据库内核构建的流式数据湖平台(Streaming Data Lake Platform)是最佳方式。这个定义中有几个关键词非常重要。

使用flinkhudi构建流式数据湖:Apache Hudi 新一代流式数据湖平台(2)

Streaming:其核心在于通过优化快速更新(upsert)和更改流(change stream),Hudi 为数据湖工作负载提供了原语,这些原语与 Apache Kafka[15] 为事件流所做的相当(即事件的增量生产 / 消费和用于交互式查询的状态存储) 。

DataLake:尽管如此,Hudi 为湖上(可以说是世界上最大的事务湖 [16])大规模数据处理(即席查询、ML 管道、批处理管道)提供了一个优化的、自我管理的数据平面。虽然 Hudi 可用于构建 LakeHouse[17],但鉴于其事务能力,Hudi 能做的不止于此,并进一步解锁了端到端的流处理架构。相比之下,“Streaming”这个词在 LakeHouse 论文 [18] 里只出现了 3 次,其中一次还是在谈论 Hudi 时提到的。

Platform:开源世界里有很多很棒的技术,但有点太多了——所有这些技术在各自领域都略有不同,最终使终端用户的集成任务变得繁重。数据湖用户应该获得与云数仓相同且出色的可用性,以及开源社区真正的额外自由和透明度。Hudi 的数据和表格服务与 Hudi“内核”紧密集成,使我们能够以可靠性和易用性提供跨层的优化。

Hudi 组件栈

以下堆栈描绘了构成 Hudi 的软件组件层,每一层都依赖于并从下一层汲取力量。通常,数据湖用户将数据写入开放的文件格式(如 Apache Parquet[19] / ORC[20]),这些文件格式存储在高度可扩展的云存储或分布式文件系统之上。Hudi 提供了一个自管理的数据平面来摄取、转换和管理这些数据并解锁了对它们进行增量处理的方式。

使用flinkhudi构建流式数据湖:Apache Hudi 新一代流式数据湖平台(3)

此外,Hudi 已经提供或计划添加组件以使所有不同的查询引擎都普遍可以访问这些数据。带 * 注释的功能代表正在进行的工作,虚线框代表规划中未来将展开的工作。虽然我们在博客中为新组件概述了假想的设计,但我们也非常欢迎来自社区的新观点。博客的其余部分将深入研究堆栈中的每一层 - 解释它的作用、它如何设计用于增量处理以及它将如何发展。

湖存储

Hudi 使用 Hadoop FileSystem API[21] 与湖存储交互,这使其能够兼容从 HDFS 到云存储甚至内存文件系统(如 Alluxio[22]/Ignite)的所有实现。Hudi 内部实现了自己包装过的文件系统 [23],以提供额外的存储优化(例如:文件大小)、性能优化(例如:缓冲)和指标体系。值得一提的是,Hudi 充分利用了像 HDFS 之类的存储模式所支持的“append"特性。这有助于 Hudi 提供流式写入,而不会导致文件计数 / 表元数据激增。不幸的是,目前大多数云 / 对象存储都不提供“append”功能(Azure 除外 [24])。未来我们计划利用主流云对象存储的低级 API,在流式摄取延迟时提供对文件计数的类似控制。

文件格式

Hudi 是围绕基本文件和增量日志文件的概念设计的,它们将更新 / 增量数据存储到给定的基本文件(称为文件片,file slice)。它们的格式是可插拔的,目前支持的基本文件格式包括 Parquet(列访问)和 HFile(索引访问)。增量日志以 Avro[25](面向行)格式对数据进行编码,以实现更快的日志记录(就像 Kafka topic 一样)。展望未来,我们计划在即将发布的版本中将每种基本文件格式内联到日志块中 [26],根据块大小提供对增量日志的列式访问。未来的计划还包括支持 ORC 基础 / 日志文件格式、非结构化数据格式(自由的 json 格式、图像),甚至使用事件流系统 /OLAP 引擎 / 数仓的分层存储层的原生文件格式。

从另外一方面看,Hudi 独特的文件布局方案将给定基础文件的所有更改编码为一系列块(数据块、删除块、回滚块),这些块被合并以派生出更新的基础文件。本质上这构成了一个自包含的重做日志,可以在上面实现有趣的功能。例如,当今的大多数数据隐私保护条例都是通过在读取湖中数据时进行动态编码的机制,在同一组记录上一遍又一遍地调用散列 / 加密算法并产生大量计算开销 / 成本来实现的。基于 Hudi 的这种设计,用户将能够在日志中保留相同键的多个预先编码 / 加密的副本,并根据策略分发正确的副本,从而避免以上提及的开销。

使用flinkhudi构建流式数据湖:Apache Hudi 新一代流式数据湖平台(4)

表格式

“表格式”这个术语比较新,对很多人来说同时意味着很多东西。与文件格式类比,表格式仅包括:表的文件布局、表的 schema 和对表更改的元数据跟踪。Hudi 并不将自己定位为一种表格式,不过它自身确实内置实现了一种格式。Hudi 使用 Avro 模式来存储、管理和演进表的 schema。目前 Hudi 强制执行 schema-on-write,虽然比 schema-on-read 更严格,但在流处理领域被广泛采用 [27],以确保管道不会因无法向后兼容的变更而中断。

Hudi 有意识地将表 / 分区中的文件分组,并维护摄入记录的键与现有文件组之间的映射。所有更新都记录到特定于给定文件组的增量日志文件中,与 Hive ACID 等实现机制相比,这种设计确保了较低的合并开销,后者必须针对所有基本文件和所有增量记录来评估合并才能满足查询。例如,使用 uuid 做主键(场景非常广泛)所有基本文件很可能与所有增量日志所包含的记录重叠,从而使任何基于范围的剪枝优化变得无用。与状态存储非常相似,Hudi 的设计理念基于键的快速 upserts/deletes,并且只需要在每个文件组中合并 delta 日志。这种设计选择还让 Hudi 为写入 / 查询提供了更多的能力,我们将在下面解释。

使用flinkhudi构建流式数据湖:Apache Hudi 新一代流式数据湖平台(5)

猜您喜欢: