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

383 阅读5分钟

数据湖三剑客:Delta Lake、Hudi与Icebreg详解

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

1.发展历史

1.1数据湖发展阶段-hadoop

优点
  • 同一公司/组织可以使用共享存储
  • 数据访问方便,灵活性高
缺点
  • 没有记录文件的schema(包括列名、列类型),经常使用Schema on Query的方式
  • 难以得知数据集包含了那些文件,是通过什么样的分区组织的
  • 如果多个程序都在修改这个数据集(修改数据、修改表结构),其他程序难以配合做修改

1.2数据湖发展阶段2-Hive

对数据湖的演进--Hive Metastore

优点
  • 对数据湖中的数据集进行集中“定义”
缺点
  • 当A/B同时读分区/20220623下的文件,当Writer B重写分区时,Reader A和B读到的文件可能是不同的
  • HIVE allows us to add column after last column only

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

数据仓库成本高、存储计算不分离、是ACID 数据湖成本低、存储计算是分离的、否ACID 湖仓一体:结合了数据湖和数据仓库的优势

1.4业界三大数据湖

Delta Lake、Hudi与Icebreg

1.5关于“数据湖”

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

2.核心技术

2.1文件结构

写入数据湖时
  1. 按照每条数据的date进行分区
  2. 额外使用metadata文件记录表信息

2.2Time travel

  1. 每一次写入操作,创建一个新的json文件,以递增版本号命名,记录本次新增/删除的文件
  2. 每当产生N个jsson,做一次聚合,记录完整的分区文件信息
  3. 用checkpoint记录上次做聚合的版本号
要点
  1. 每次写入都生成一个新的元数据文件,记录变更
  2. 分区数据在Update时,不要删除旧数据,保证新旧共享
  3. 元数据中存储具体的文件路径,而不仅仅是分区文件

2.3Transaction

  • ACID:是指数据库在写入或更新资料的过程中,为保证事务是正确可靠的,所必须具备的四个特性。
  • Atomicity:原子性--要么A-10 B+10,要么都不变
  • Consistency:一致性--不可以A-10 B+5
  • Isolation:事务隔离--A和C同时给B转10,B最终结果应是+20
  • Durability:持久性--转账服务器重启,结果不变

2.3.1原子性例子

  • 写入parquet 数据文件(data)
  • 写入json元数据文件(metadata)
保证原子性例子
  1. 用户只会读取以版本号数字命名的json文件,每次都读取到最大的版本号作为数据集的现状
  2. 新的写入写完parquet后开始写json问价,使用hash值对json文件命名,如a2fs4hfg8ee.json
  3. 直到json文件内容写入完毕,利用hdfs的renameIfAbsent能力将a2fs4hfg8ee.json替换为000006.json,到此为止commit完成,新的读取将会以000006.json作为最新版本

2.3.2事务隔离

Update写入流程
  1. 从最新的版本中,获取需要update的分区
  2. 乐观锁先把该写入的文件全落盘,然后进入写json阶段
  3. 分几种情况:
    • 发现版本号和一开始没区别,直接写信的版本;
    • 发现版本号增加了,看看新增的这些版本有没有更新我要更新的分区
      • 没有,直接写新的版本
      • 有,两者都更新了同一分区,得重新update了

2.4 Schvema Evolution

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

  1. 唯一确定的ID。新增列赋予新ID。删列ID不重复。
  2. 写入数据时,ID也写入数据文件
  3. 读取数据时,用ID做映射,如果:
    • Data中没有,metadata中有有:add
    • Data中有,metadata中没有:drop
    • Data和metadata中都有同一ID,但是name不同:RENAME
    • 如果都有同一列名,而ID不同?

3.各有所长

3.1Iceberg工作重点

用户体验
  1. Schema evolution
  2. Partion evolution
  3. Hidden partition
  4. Time Travel
  5. Version Rollback
性能
  1. 快速file plan
  2. 更多的filter方式
可靠性
  1. ACID Transaction
  2. 完全开源,由Apache孵化开发
  • well-designed Metadata Layer:通过分层存储将元数据分离开了
  • Data File Filter:快速分区裁剪,带来了极大的性能优化
  • Hidden Partition:解决了传统分区方式中改变分区方式时需要新增列的问题,可以通过包含timestamp列,设置好partition transform方式。(Iceberg记录了这层转化关系,并且按你的需要进行partition evolution)

3.2 Hudi

  • Timeline Serivce:记录的信息类似于metadata
  • Upsert:每一条样本都有一个主键PK,当Upsert-条数据时,如果现有的数据中有这个PK,则update这条数据。否则直接insert这条数据
  • Incremental:某个时间点后新增的数据
  • Copy on write :我们在更新一个分区时,将原来数据读出来,进行更新再写入
  • Merge on Read:将更新写入一个单独的文件里,在读取时将这些数据一起读,以PK做一个merge,就可以将update的行以更新的形式展示出来(虽然多了一些读取的开销,但在写和存取上有更好的性能,)

3.3 Delta Lake

流批一体,部分开源…………

4.总结场景

  • Iceberg 支持:ACID transactions、Partition Evolution、Schema Evolution、Time-Travel
  • Hudi 支持:ACID transactions、Schema Evolution(partial)、Time-Travel
  • Delta Lake 支持:ACID transactions、Schema Evolution(partial)、Time-Travel

5.字节跳动数据湖场景举例--Feature Store

5.1Feature Store在字节的诞生

初心
  • instance pb样本读取放大、不能列裁剪=>很难落许多特征进样本
  • instance pb样本写放大、copy-on-write=>很难做特征回溯调研
收益
  1. 支持落原始特征做特征调研
  2. 解决读放大、支持列裁剪
  3. 解决写放大、支持列裁剪
  4. 解决写放大、支持merge-on-read
  5. 支持特征schema校验
  6. 列式存储优化存储空间
  7. Arrow格式优化序列化开销