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

128 阅读3分钟

  这是我参与「第四届青训营 」笔记创作活动的的第6天,本篇笔记对于8.2日赵汉卿老师讲授的《数据湖三剑客:Delta Lake、Hudi 与 Iceberg 详解》内容做一个复习总结。


发展历史
  • 回顾:Parquet:高性能列式存储,过滤下推到存储侧,更好地压缩性能。
  • 数据湖发展阶段:
    • Hadoop:HDFS 通过不同的目录来区分数据集,易共享,访问方便灵活,缺点是没有记录文件的 schema,难以得知数据集包含的文件通过什么分区组织,如果多个程序修改一个数据会难以控制。
    • Hive:MetaStore 对数据集进行了定义,包括数据湖中有哪些数据集,存储在什么目录,schema 是怎样的,数据集的分区有哪些,分区目录。缺点:仍存在读写冲突;Hive 不支持删列,只能重建新表。
    • 湖仓一体:数仓将数据从数据源提取和转换,加载到目的地,存算不分离,严格管控 schema。结合优势:ACID(数仓)、schema 管理(数仓)、存算分离(数据湖)、多引擎和文件格式支持
  • 经典的数据湖:Hudi(Uber 开发,数据写入低延迟)、Iceberg(Netflix 开发,摆脱 Hive 架构的问题)、Delta Lake(UCB、独角兽公司 databricks 开发)

核心技术
  • 文件结构:写入数据湖时,首先按照每条数据 date 分区(例子),每个分区存储了 parquet 文件,然后额外使用 metadata 文件记录表信息

  • Time travel:
    • 每次写入新生成一个元数据文件,记录变更;
    • 分区数据在更新时,不删除旧数据,新旧共存
    • 元数据要存具体的文件路径
    • 每次写入创建一个 json,每N个 json 做一次聚合并记录分区信息,checkpoint 记录上次完成的聚合版本号
    • 可以定期删一些过久数据 image.png

  • Transaction:事务性,数据湖的 ACID
    • 原子性:写入要么可见要么不可见,先写入 parquet 文件,以 Hash.parquet 文件存储,写完后写 Hash.json,写完后尝试重命名为版本号.json,如果失败就无法 commit,新写入在没有 commit 前用户无法读取(用户只读当前 最大版本号.json)
    • 一致性:计算引擎保证
    • 事务隔离:读写和写写冲突,由于新写入不替换原数据,故读写冲突已解决。Update 时采用乐观锁,先全写文件,进入写 json,看版本号有无变化,若变化,查看新增版本是否更新我要更新的分区,没有则写新版本,有则重新 update。
    • 持久性:存储引擎保证

  • Schema Evolutio
    • 用户不直接读 parquet 文件,通过数据湖接口读取分区 parquet,数据湖读取时在 schema 上处理
    • ID 将 data 和 metadata 的列名一一对应,删除 ID 不会复用,写入数据时,ID 写入数据文件,读取时:
      • Data 没有 metadata 有:刚 ADD
      • Data 有 metadata 无:刚 DROP(读取时不读)
      • Data 有 metadata 有但名字不同:刚 RENAME
      • 同一 NAME ID不同:删了又加了

(待补充)