Delta Lake、Hudi与Iceberg详解 | 青训营笔记

142 阅读5分钟

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

1. 发展历史

HDFS:难管理

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

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

  • 好处:

    • 同一公司/组织可以使用共享存储
    • 数据访问方便,灵活性高
  • 坏处:

    • 没有记录文件的schema(包括列名、列类型),经常使用schema on Query的方式
    • 难以得知数据集包含了哪些文件,是通过什么样的分区组织
    • 如果对个程序都在修改这个数据(修改数据、修改表结构),其他程序难以配合做修改

Hive:

对数据湖的演进——Hive Metastore

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

    • 他们都存在什么目录
    • 数据集的schema是什么样子的
    • 数据集有哪些分区,每个分区的目录是什么

数据仓库:

数据仓库是将数据从数据源提取和转换,加载到目的地

湖仓一体

数据仓库数据湖(阶段一)
成本
存储计算分离
ACID

关于数据湖:

  • 数据相关概念比较新,一直处在演进当中
  • 一开始是 HDFS ,裸pb、txt 日志等,叫数据湖(管不了了就是数据沼泽)
  • Iceberg、Hudi、Delta Lake,数据湖概念基本等于这些产品

2. 核心技术

Time travel:

要点:

  • 每次写入都生成一个新的元数据文件,记录变更
  • 分区数据在 Update 时,不要删除旧数据,保证新旧共存
  • 元数据中存储具体的文件路径,而不仅仅是分区文件夹

写入流程”

  1. 写入parquet数据文件
  2. 写入 json 元数据文件

读写冲突:

如何确保原子性?(从用户可见性入手)

  1. 用户只会读取以版本号数字命名的json文件,每次都读取到最大的版本号作为数据集的现状
  2. 新的写入写完parquet后开始写json文件,使用hash值对json文件命名a2fs4hfg8ee.json
  3. 直到json文件内容写入完毕,利用hdfs的renameIfAbsent能力将a2fs4hfg8ee.json ,到此为止 commit 完成,新的读取将会以 000006.json作为最新的版本

读写冲突已经解决:

  1. 新的写入除非已经commit,否则用户读不到
  2. 用户正在读的分区,被另一个写入进行了更新,数据不会进行替换,而是共存

写写冲突:

写写冲突insertupdate/delete
insertcan not conflict
update/deletecan conflictcan conflict

update 写入流程:

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

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

  3. 分几种情况:

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

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

      • 没有,直接写新的版本
      • 有,两者更新了同一分区,得重新update了

Schema Evolution

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

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

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

  • 读取数据时,用 ID 做映射,如果

    • data 中没有,metadata 中有:ADD
    • Data 中有,metadata 中没有:DROP
    • Data 和 metadata 中都有同一个 ID ,但是 name 不同:RENAME
    • 如果都有同一列名,而 ID 不同?先增加,再删除

3. 各有所长

Iceberg 工作重点

用户体验:

  1. Schema evolution
  2. partition evolution
  3. hidden partition
  4. time travel
  5. version rollback

性能:

  1. 快速 file plan
  2. 更多的 filter 方式

可靠性:

ACID transaction

完全开源,由Apache 孵化开发

well-designed Metadate Layer

Metadata files 定义了表结构,存储了snapshot 信息,分区列信息等 Manifest lists 存储了一个 snapshot 中所有 manifest的信息 Manifests 存储了一些 data files 的信息 Data files 就是具体的数据文件

well-designed Metadate Layer.jpg

well-designed Metadate Layer.jpg

data file filter

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

  1. Manifest file 记录了每个 data file 的分区范围
  2. Manifest list 记录了每个 manifest file 的分区范围分区可以被快速定位!可以做manifest list 级别裁剪.
  3. Manifest file 记录了每个 data file 每一列的最大值,最小值可以通过其他的列 (Userld) 做data file 级别裁剪。

Hidden Partition(隐藏分区)

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

lceberg的分区方式: 数据中包含 timestamp 列,设置好 partition transform 方式

  • 设置为 date 时,iceberg 帮你转化为 date 分区 设置为 hour时,iceberg 帮你转化为 hour 分区 lceberg 记录了这层转化关系,并且按你的需要进行 partition evolution

Hudi

Hadoop Upsert Delete and Incremental Hudi工作重点:

  1. Timeline service: Hudi 管理 transaction 的方式
  2. Hudi Table Type: Copy on Write / Merge on Read
  3. 高效的 Upserts: update or insert
  4. 素引表:快速定位一条数据的位置
  5. Streaming Ingestion Service
  6. 完全开源,由 Apache 孵化

Timeline Srrivce & Upsert & Incremental

  • Timeline Service: 记录的信息类似于metadata
  • Upsert: 每一条样本都有一个主健PK, 当Upsert一条数据时,如果现有的数据中有这个PK,则 update 这条数据。否则白接 insert 这条数据
  • Incremental: 某个时间点后新增的数据

Timeline Srrivce & Upsert & Incremental.jpg

Copy on write

copy on write.jpg

Merge On Read

Merge On Read.jpg

Delta Lake 工作重点

  1. ACID Transaction
  2. Schema 校验(不是evolution)
  3. 流批一体
  4. Time Travel
  5. Upsert/Delete
  6. Z-Order 174
  7. 只开源了一部分,由 Databricks 自己主导开发,Z-order 等优化的实现末开源

流批一体

流批一体.jpg