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

122 阅读3分钟

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

数据湖发展阶段

1. Hadoop:HDFS 使用不同的目录来区分数据集

优点

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

缺点

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

2. Hive:对数据湖的演进--Hive Metastore

优点

  • 对数据湖中的数据集进行集中“定义”,包括数据湖中有哪些数据集;存储在什么目录;数据集的schema 是怎样的;数据集有哪些分区,分区目录是什么。

缺点

  • 仍存在读写冲突
  • Hive 不支持删列,只能重建新表。

3. 湖仓一体

  • 数据仓库要保证存算一体,然后又要保证数据是结构化的,成本比较高,随时需要拿出来计算。
  • 数据湖主要是负责存数据,格式也没有结构化的要求,直接存原始数据,并且不需要计算的。
  • 湖仓一体是一种结合了数据湖和数据仓库优势的新范式,在用于数据湖的低成本存储上,实现数据仓库对数据的严格要求。

经典的数据湖

Hudi(Uber 开发,数据写入低延迟)、Iceberg(Netflix 开发,摆脱 Hive 架构的问题)、Delta Lake(databricks 开发,主打湖仓一体)

设计一个简单的数据湖

文件结构

写入数据湖时:

  • 按照每条数据的date进行分区
  • 额外使用metadata文件记录表信息

Time travel

  • 每一次写入操作,创建一个新的json文件,以递增版本号命名,记录本次新增/删除的文件
  • 每当产生N个json,做一次聚合,记录完整的分区文件信息
  • 用checkpoint记录上次做聚合的版本号

要点:

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

Transaction

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

以A给B转账10元为例:

  • Atomicity:原子性--要么A-10 B+10,要么都不变
  • Consistency:一致性--不可以A-10 B+5
  • Isolation:事务隔离--A和C同时给B转10,B最终结果应是+20
  • Durability:持久性--转账服务器重启,结果不变

数据湖中的ACID:

  • Atomicity:原子性--本次写入要么对用户可见,要么不可见(需要设计)
  • Consistency:一致性--输入是什么,落盘的就是什么(由计算引擎保证)
  • Isolation:事务隔离--正确解决读写冲突和写写冲突(需要设计)
  • Durability:持久性--落完数据后,即便服务器重启结果不变(由存储引擎保证)

选型标准

  • 项目功能
    • 如果强需求Upserts,Hudi更适合
    • 如果希望可扩展性强,Iceberg更适合
    • 如果希望用上Z-Order等优化,Databricks 的企业版Delta更适合

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

  1. 需要的feature在哪个数据湖上是最稳定的
  2. 哪个数据湖能够用最简单的接入方式( SQL )用上最完善的功能
  3. 哪一个数据湖有计算引擎和社区的支持
  4. 哪一个数据湖的版本管理做的最好