数据湖三剑客:Delta Lake、Hudi 与 Iceberg 详解| 青训营笔记

257 阅读6分钟

image.png 这是我参与「第四届青训营 」笔记创作活动的的第7天

今天的笔记主要分为四个部分:
一、发展历史
二、核心技术
三、各有所长
四、总结场景

一、发展历史

1.数据湖发展阶段-Hadoop

数据湖最开始的概念--分布式存储HDFS

使用目录来区分不同的数据集

好处:

-同一公司/组织可以使用共享存储

-数据访问方便,灵活性高

坏处:

-没有记录文件的schema,经常使用schema on query的方式

-难以得知数据集包含了哪些文件,是通过什么样的分区组织的

-如果多个程序都在修改这个数据集,其他程序难以配合做修改

image.png

2.数据湖发展阶段-Hive

数据湖的演进--Hive Metastore

对数据湖中的数据集进行集中“定义”

-数据湖中存在了哪些数据集

-他们都存储在什么目录

-数据集的schema是什么样子的

-数据集有哪些分区,每个分区的目录是什么

image.png

3.数据湖的发展阶段-湖仓一体

湖仓一体:

-结合了数据湖和数据仓库的优势

-将数据仓库中对于数据的严格管理直接实现到了低成本的分布式存储之上

-Key Features:Transaction ACID、Schema管理、存储计算分离、支持多种计算引擎和文件格式

image.png

4.关于数据湖

-数据相关概念比较新,一直处在演进当中

-一开始是HDFS,裸pb、txt日志等等,叫数据湖

-后来出现了Iceberg、Hudi、Delta Lake了,数据湖概念就基本等于这些产品了

-也更贴近于Lakehouse的概念

二、核心技术

1.文件结构

写入数据湖时:

-按照每条数据的date进行分区

-额外使用metadata文件记录表信息

2.Time Travel

要点:

-每次写入都生成一个新的元数据文件,记录变更

-分区数据在Update时,不要删除旧数据,保存新旧共存

-元数据中存储具体的文件路径,而不仅仅是分区文件夹

-每一次写入操作,创建一个新的json文件,以递增版本号命名,记录本次新增/删除的文件

-每当产生N个json,做一次聚合,记录完整的分区文件信息

-用checkpoint记录上次做聚合的版本

3.Transaction

ACID,是指数据库在写入或更新资料的过程中,为保证事务是正确可靠的,所必须具备地四个特性。

数据湖中的ACID:

-Atomicity:原子性,本次写入要么对用户可见,要么对用户不可见

-Consistency:一致性,输入是什么,落盘的就是什么

-Isolation:事务隔离,正确解决读写冲突和写写冲突

-Durability:持久性,落完数据后,即便服务器重启结果不变

3.1原子性

写入流程:

-写入parquet数据文件

-写入json元数据文件

读写冲突已经被解决,how?

-新的写入除非已经commit,否则用户读不到

-用户正在读的分区,被另一个写入进行了更新,数据不会进行替换,而是共存

image.png

3.2事务隔离

image.png

Update写入流程:

-从最新的版本中,获取需要update的分区

-乐观锁先把该写入的文件全落盘,然后进入写json阶段

-分几种情况:

--发现版本号和一开始没区别,直接写新的版本

--发现版本号增加了,看看新增的这些版本有没有更新我要更新的分区?

---没有,直接写新的版本

---有,两者都更新了同一分区,得重新update

4.Schema Evolution

Add/Drop/Rename

重要:

-用户并不直接读取parquet文件本身,而是通过数据湖接口读取

-数据湖内部会读取应该读的parquet,并在schema上做进一步处理

ID将data和metadata的列名做一一对应

-唯一确定的ID。新增列赋予新ID,删列ID不复用

-写入数据时,ID也写入数据文件

-读取数据时,用ID做映射

三、各有所长

  1. Iceberg工作重点

用户体验:

-Schema evolution

-Partition evolution

-Hidden partition

-Time Travel

-Version Rollback

性能:

-快速file plan

-更多的filter方式

可靠性:

-ACID Transaction

完全开源,由Apache孵化开发

1.1 Well-designed Metadata Layer

-Metadata files定义了表结构,存储了snaphsot信息,分区列信息等

-Manifest lists存储了一个snapshot中所有manifest的信息

-Manifest存储了一些data files的信息

-Data files就是具体的数据文件

image.png

1.2 Data File Filter

一些有助于filter的数据被层层记录,比如:

-Manifest file记录了每个data file的分区范围

-Manifest list记录了每个manifest file的分区范围,分区可以被快速定位。可以做manifestlist级别裁剪

-Manifest file记录了每个data file每一列的最大值,最小值可以通过其他的列做data file级别裁剪

1.3 Hidden Partition

传统的分区方式:

数据中包含了date列,则按照date分区;如果希望按照hour分区,则需要新增hour列

Iceberg的分区方式:

数据中包含timestamp列,设置好partition transform方式

-设置为date时,iceberg帮你转化为date分区

-设置为hour时,iceberg帮你转化为hour分区

-Iceberg记录了这层转化关系,并且按照你的需要进行partition evolution

  1. Hudi

Hadoop Upset Delete and Incremental

Hudi工作重点:

-Timeline service:Hudi管理transaction的方式

-Hudi Table Type:Copy on Write/Merge on Read

-高效的Upsets:upset or insert

-索引表:快速定位一条数据的位置

2.1 Timeline Service & Upset & Incremental

-Timeline Service:记录的信息类似于metadata

-Upsert:每一条样本都含有一个主键PK,当Upsert一条数据时,如果现有的数据中有这个PK,则update这条数据,否则直接insert这条数据

-Incremental:某个时间点后新增的数据

image.png

2.2 Copy on Write

image.png

2.3 Merge on Road

image.png

3.Delta Lake工作重点

-ACID Transaction

-Schema校验

-流批一体

-Time Travel

-Upsert/Delete

-Z-Order优化

-只开源了一部分,由Databricks自己主导开发,Z-order等优化的实现未开源

3.1流批一体

image.png

四、总结场景

1.三个数据湖的异同

image.png

2.三个数据湖的热度

image.png

image.png

3.技术选型

短期来看:每个项目都有一些属于自己的功能:

-如果强需求Upserts,也许Hudi是最好的选择

-如果希望可扩展性强,那么设计优良的Iceberg是最好的选择

-如果希望用上了Z-Order等优化,那么掏钱买Databricks的企业版Delta是不二之选

长期来看:数据湖取代Hive,成为HDFS上的表格式标准是必然的,在选择之前问自己四个问题:

-我需要的feature在哪个数据湖上是最稳当的

-哪一个数据湖能够用最简单的接入方式用上最完善的功能

-哪一个数据湖有计算引擎侧的支持和社区的支持

-哪一个数据湖的版本管理做的最好,最鲁棒

4.课程总结

-数据湖的最新发展状态是湖仓一体

-数据湖以低存储成本提供了ACID Transaction、Schema evolution、Time travel等高级功能