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

235 阅读2分钟

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

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

数据湖核心技术

文件结构

用户要求:

image.png 路径: image.png 代码实现(json形式):

{
    "schema":[
        {
            "name":"userID",
            "type":"int"
        },
        {
            "name":"date",
            "type":"string"
        },
        {
            "name":"event",
            "type":"string"
        },
        {
            "name":"phonenumber",
            "type":"string"
        }
    ],
    "partition_col":"date",
    "location":"mytable/",
    "partition":[
        "2020-01-01",
        "2020-01-02"
    ]
}

Time travel

用户要求: image.png 路径: image.png 代码实现(json形式):

{
    "schema":[
        {
            "name":"userID",
            "type":"int"
        },
        {
            "name":"date",
            "type":"string"
        },
        {
            "name":"event",
            "type":"string"
        },
        {
            "name":"phonenumber",
            "type":"string"
        }
    ],
    "partition_col":"date",
    "location":"mytable/",
    "partition":[
        {
            "2020-01-01";[
                "xxx.parquet" ,
                "yyy.pqrquet"
            ],
             "2020-01-02";[
                "xxx.parquet" ,
                "yyy.pqrquet"
            ]
        }
    ]
}

Transaction

数据湖中的ACID:

  1. Atomicity:原子性-本次写入要么对用户可见,要么不可见
  2. Consistency:一致性-输入是说明,落盘就是什么
  3. Isolation:事务隔离-正确解决读写冲突和写写冲突
  4. Durability:持久性-落完数据后,即便服务器重启结果不变

用户要求: image.png 路径: image.png 实现:

  • 写入流程:
    1. 写入 parquet 数据文件
    2. 写入 json 元数据文件
  • 读写冲突(保证原子性):
    1. 用户只会读取以版本号数字命名的json文件,每次都读取到最大的版本号作为数据集的现状
    2. 新的写入写完parquet后开始写json文件,使用hash之对json文件命名,如a2fs4hfg8ee.json
    3. 直到json文件内容写入完毕,利用hdfs的renameIfAbsent能力将a2fs4hfg8ee.json替换为000006.json,到此commit完成,新的读取将会以000006.json作为最新版本
  • 写写冲突:
    • Update写入流程:
      1. 从最新的版本中,获取需要update的分区

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

      3. 分以下两种情况

        1. 发现版本号和一开始没区别,直接写入新的版本
        2. 发现版本号增加了,看看新增的这些版本有没有更新我要更新的分区?
          1. 没有,直接写新的版本。
          2. 有,两者都更新了同一分区,需要重新update。