在花了大约 4 年时间致力于 Apache Hudi(其中包括 3 年Committer身份)之后,我决定开始这个博客系列,旨在以有组织且适合初学者的方式展示 Hudi 的设计和用法。 我的目标是确保对分布式数据系统有一定了解的人能够轻松地理解该系列。 该系列将包含 10 篇文章,每篇文章都会深入探讨 Hudi 的一个关键方面。 (为什么是 10?纯粹是对 0 和 1 的有趣致敬,与系列标题相呼应:))最终目标是帮助读者从广度和深度上理解 Hudi,使他们能够自信地利用这个开源项目并为其做出贡献。 在撰写本文时,Hudi 0.14.0 正处于候选版本阶段。 因此,整个系列以及配套代码和示例都将基于此版本。

概述

Hudi 是一个事务性数据湖平台,它将数据库和数据仓库功能引入数据湖。 下图摘自 Hudi 社区举办的网络研讨会,清楚地说明了该平台的主要功能

Hudi 的核心定义了一种表格式,用于组织存储系统内的数据和元数据文件,从而实现 ACID 事务、高效索引和增量处理等功能。 本文的其余部分将探讨格式详细信息,主要展示存储上的 Hudi 表的结构并解释不同文件的角色。

存储格式

下图描述了 Hudi 表在存储中的基本路径下的典型数据布局。

有两种主要类型的文件:位于 .hoodie/ 目录中的元数据文件,以及存储在分区路径中(如果表已分区)的数据文件,或者直接在基本路径(如果未分区)下的数据文件。

元数据

<base path>/.hoodie/hoodie.properties 文件包含基本的表配置,例如表名称和版本,表的写入端和读取端都将遵守和使用这些配置。

除了 hoodie.properties 之外,还有将事务操作记录到表中的元文件,形成 Hudi 表的时间轴。

# an example of deltacommit actions on Timeline
20230827233828740.deltacommit.requested
20230827233828740.deltacommit.inflight
20230827233828740.deltacommit

这些元文件遵循以下命名模式:

<action timestamp>.<action type>[.<action state>]

"action timestamp"

  • 标记第一次计划运行操作的时间。
  • 唯一标识时间轴上的操作。
  • 在时间轴上的不同操作之间单调递增。

"action type"显示该动作做出了什么样的改变。 有一些写入操作类型,例如 commit 和 deltacommit,它们指示表上发生的新写入操作(插入、更新或删除)。 此外,还有表服务操作,例如压缩和清理,以及恢复操作,例如保存点和恢复。 我们将在以后的帖子中更详细地讨论不同的操作类型。

"action state"可以是“已请求”、“进行中”或“已完成”(没有后缀)。 顾名思义,“已请求”表示正在计划运行,“正在执行”表示正在进行中,“已完成”表示操作已完成。

这些操作的元文件采用 JSON 或 AVRO 格式,包含有关应应用于表或已应用的更改的信息。 保留这些事务日志可以重新创建表的状态,实现快照隔离,并通过并发控制机制协调写入器冲突。

.hoodie/ 下还存储有其他元数据文件和目录。 举一些例子,元数据包含与时间轴上的操作相关的更多元数据,并充当写入端和读取端的索引。 .heartbeat/ 目录存储用于心跳管理的文件,而 .aux/ 则保留用于各种辅助目的。

数据

Hudi将物理数据文件分为Base File(基本文件)和Log File(日志文件):

  • 基本文件包含 Hudi 表中的主要存储记录,并针对读取进行了优化。
  • 日志文件包含其关联基本文件之上的记录更改,并针对写入进行了优化。

在 Hudi 表的分区路径中(如前面的布局图所示),单个基本文件及其关联的日志文件(可以没有或多个)被分组在一起作为文件切片。 多个文件切片构成一个文件组。 文件组和文件切片都是逻辑概念,旨在封装物理文件,从而简化读取端和写入端的访问和操作。 通过定义这些模型,Hudi 可以

  • 满足读写效率要求。 通常基本文件配置为列式文件格式(例如 Apache Parquet),日志文件设置为基于行的文件格式(例如 Apache Avro)。
  • 实现跨提交操作的版本控制。 每个文件切片都与时间轴上操作的特定时间戳相关联,文件组中的文件切片本质上跟踪所包含的记录如何随时间演变。

可以快速查看此处的 Hudi 表示例,了解数据布局。

表格类型

Hudi 定义了两种表类型 - 写入时复制 (CoW) 和读取时合并 (MoR)。 布局差异如下:与 MoR 相比,CoW 没有日志文件,并且写入操作会导致 .commit 操作而不是 .deltacommit。 在我们的讨论中,我们一直以 MoR 为例。 一旦掌握了 MoR,理解 CoW 就变得简单了 - 可以将 CoW 视为 MoR 的特殊情况,其中基本文件中的记录和更改在每次写入操作期间隐式合并到新的基本文件中。 可以在此处浏览示例 CoW 表。

在为 Hudi 表选择表类型时,考虑读取和写入模式非常重要,因为这会产生一些影响:

  • 由于每次写入都会重写新文件切片中的记录,因此 CoW 具有较高的写入放大,而读取操作始终会得到优化。 这非常适合读取繁重的分析工作负载或小型表。
  • MoR 的写入放大较低,因为更改会“缓冲”在日志文件中,并进行批处理以合并和创建新的文件切片。 但是,读取延迟会受到影响,因为读取最新记录需要将日志文件与基本文件进行实时合并。

用户还可以选择仅读取 MoR 表的基本文件,以提高效率,同时牺牲结果的新鲜度。 我们将在接下来的帖子中详细讨论 Hudi 的不同阅读模式。 随着 Hudi 项目的发展,与从 MoR 表读取相关的合并成本在过去的版本中得到了优化。 可以预见 MoR 将成为大多数工作负载场景的首选表类型。

回顾

在零到一系列的第一篇文章中,我们探讨了 Hudi 存储格式的基本概念,以阐明元数据和数据在 Hudi 表中的结构。 我们还简要解释了不同的表类型及其权衡。 如概览图所示,Hudi 作为一个综合性 Lakehouse 平台,提供不同维度的功能。 在接下来的九篇文章中,我将逐步介绍该平台的其他重要方面。

Apache Hudi从零到一:存储格式初探的更多相关文章

  1. Apache Hudi 设计与架构最强解读

    感谢 Apache Hudi contributor:王祥虎 翻译&供稿. 欢迎关注微信公众号:ApacheHudi 本文将介绍Apache Hudi的基本概念.设计以及总体基础架构. 1.简 ...

  2. 使用Apache Hudi构建大规模、事务性数据湖

    一个近期由Hudi PMC & Uber Senior Engineering Manager Nishith Agarwal分享的Talk 关于Nishith Agarwal更详细的介绍,主 ...

  3. Apache Hudi和Presto的前世今生

    一篇由Apache Hudi PMC Bhavani Sudha Saktheeswaran和AWS Presto团队工程师Brandon Scheller分享Apache Hudi和Presto集成 ...

  4. 使用Apache Hudi + Amazon S3 + Amazon EMR + AWS DMS构建数据湖

    1. 引入 数据湖使组织能够在更短的时间内利用多个源的数据,而不同角色用户可以以不同的方式协作和分析数据,从而实现更好.更快的决策.Amazon Simple Storage Service(amaz ...

  5. 在AWS Glue中使用Apache Hudi

    1. Glue与Hudi简介 AWS Glue AWS Glue是Amazon Web Services(AWS)云平台推出的一款无服务器(Serverless)的大数据分析服务.对于不了解该产品的读 ...

  6. 基于Apache Hudi构建数据湖的典型应用场景介绍

    1. 传统数据湖存在的问题与挑战 传统数据湖解决方案中,常用Hive来构建T+1级别的数据仓库,通过HDFS存储实现海量数据的存储与水平扩容,通过Hive实现元数据的管理以及数据操作的SQL化.虽然能 ...

  7. 基于Apache Hudi 的CDC数据入湖

    作者:李少锋 文章目录: 一.CDC背景介绍 二.CDC数据入湖 三.Hudi核心设计 四.Hudi未来规划 1. CDC背景介绍 首先我们介绍什么是CDC?CDC的全称是Change data Ca ...

  8. 基于Apache Hudi在Google云构建数据湖平台

    自从计算机出现以来,我们一直在尝试寻找计算机存储一些信息的方法,存储在计算机上的信息(也称为数据)有多种形式,数据变得如此重要,以至于信息现在已成为触手可及的商品.多年来数据以多种方式存储在计算机中, ...

  9. Apache Hudi 0.9.0版本重磅发布!更强大的流式数据湖平台

    1. 重点特性 1.1 Spark SQL支持 0.9.0 添加了对使用 Spark SQL 的 DDL/DML 的支持,朝着使所有角色(非工程师.分析师等)更容易访问和操作 Hudi 迈出了一大步. ...

  10. Apache Hudi 介绍与应用

    Apache Hudi Apache Hudi 在基于 HDFS/S3 数据存储之上,提供了两种流原语: 插入更新 增量拉取 一般来说,我们会将大量数据存储到HDFS/S3,新数据增量写入,而旧数据鲜 ...

随机推荐

  1. NC16886 [NOI2001]炮兵阵地

    题目链接 题目 题目描述 司令部的将军们打算在N*M的网格地图上部署他们的炮兵部队.一个N*M的地图由N行M列组成,地图的每一格可能是山地(用"H" 表示),也可能是平原(用&qu ...

  2. UVA11573 Ocean Currents

    题目链接 题目 见链接. 题解 知识点:BFS. 这道题显然用BFS,但发现洋流方向会破坏时间的有序性,但注意到洋流时间花费是 \(0\) ,因此只需要用双端队列即可,洋流方向扩展直接放队头,其他方向 ...

  3. C++ 快速加载 Dll 里的 API

    最近项目里要重新编写程序加载器,也就是编译出一个可执行文件,在 Windows 上是 .exe 为什么要程序加载器? 个人理解是,可执行文件大小最好是越小越好,功能都可以由 dll 文件执行 而程序加 ...

  4. Ubuntu常用工具和问题整理

    安装Ubuntu虚拟机时常会遇到的几个问题 1.安装时设置镜像 安装Ubuntu系统时设置国内镜像可以加快安装速度:http://mirrors.aliyun.com/ubuntu/ 参考:ubunt ...

  5. 一个Git Commit Message模板

    一个统一的commit消息模板可以约束团队成员使用一致的方式提交变更信息,这样也方便集成工具进行合规检查. 通常来讲,commit信息应该包含如下内容: <type>(<scope& ...

  6. mac更新系统后,提示xcrun的错误问题

    pycharm运行代码终端报错: xcrun: error: invalid active developer path (/Library/Developer/CommandLineTools), ...

  7. 用virtualenv创建虚拟环境

    步骤 1.打开终端cmd,直接输入命令pip install virtualenv,前提已经将pip加入到环境变量中了 2.在e盘创建一个专门用来装虚拟环境的文件夹,如django_web_env 3 ...

  8. 【LeetCode贪心#05】K 次取反后最大化的数组和(自定义sort、二重贪心)

    K次取反后最大化的数组和 力扣题目链接(opens new window) 给定一个整数数组 A,我们只能用以下方法修改该数组:我们选择某个索引 i 并将 A[i] 替换为 -A[i],然后总共重复这 ...

  9. 【C++ OOP 03 友元】各种友元例子以及如何类外写成员函数

    [友元] 在程序里,有些私有属性 也想让类外特殊的一些函数或者类进行访问,就需要用到友元的技术 友元的目的就是让一个函数或者类 访问另一个类中私有成员 友元的关键字为 friend 友元的三种实现 全 ...

  10. 谈一谈如何使用etcd中的事务

    本文内容来源于自己学习时所做的记录,主要来源于文章最后的参考链接,如有侵权,请联系删除,谢谢! etcd 是一个 key/value 类型的数据库.既然我们需要存储数据,必然会面临这样一个需求,即希望 ...