数据湖三剑客:Delta Lake、Hudi 与 Iceberg 详解|青训营笔记
这是我参与「第四届青训营」笔记创作活动的的第9天。
一、课程概述
- 介绍了数据湖、数据仓库的概念
- 介绍了湖仓一体的发展模型
- 介绍了三种不同湖仓一体的实现
二、详细内容
1.发展历史
- Hadoop
- Hive
- 湖仓一体
1.1 数据湖发展阶段 - Hadoop
- 数据湖最开始的概念——分布式存储 HDFS
- 使用目录来区分不同的数据集
- 好处
- 同一公司/组织共享存储
- 数据访问方便,灵活性高
- 坏处
- 没有记录文件的schema,使用schema on query方式
- 难以得知数据集包含哪些文件,通过什么样的分区组织
- 若多个程序都在修改这个数据集(修改数据、表结构),其他程序难以配合做修改
- 数据沼泽
1.2 Hive
- 数据湖的演进——Hive MetaStore
- 对数据湖中数据集进行集中定义
- 那些数据集
- 什么目录
- schema
- 数据集哪些分区,每个分区目录是什么
- 如果hive表是静态的没有新增写入,则所有读取都能便捷使用
- 需要ACID/schema变更
1.3 湖仓一体
- 数据仓库
- 数据从数据源做提取,转化加载到目的地
- 存储计算不分离
- 严格控制写入schema
- 仓库成本高,数据湖成本低
- 存算分离仓库否,湖是
- ACID仓库是,湖否
- 湖仓一体
- 结合二者优势:存储成本低,有结构
- 将仓库对数据严格管理结合数据湖
- ACID schema管理 存算分离 支持多引擎格式
2.核心技术
设计一个简单的数据湖
- 按照date分区
- schema是 userid date event phone
- 每天写入新数据
- 列存格式
2.1 文件结构
- 写入数据湖时按照每条数据date进行分许
- 额外使用metadate文件记录表信息
2.2 Time travel
-
每次写入生成一个新的元数据文件,记录变更
-
分区数据update时不删除,共存
-
元数据中存储不仅数据 还包括数据的文件夹
-
每一次写入操作创建新json文件以版本号明明,记录增删文件
-
每当产生N个json做一次聚合,记录完整分区文件信息
-
用checkpoint记录上次做聚合的版本号
2.3 Transaction
- 同时写/读+写
- ACID
- atomicity 原子性 要么同时变要么不变
- consistency 一致性 不能一边少一边多
- isolation 事务隔离 两个transaction不干扰
- durability 持久性 重启不错误
- A 要么对用户可见要么不可见
- 写入parquet数据,再写入json元数据文件
- 确保原子性
- 用户只读最大数字版本号作为数据集现状
- 新写入写完parquet后写json,用hash命名
- C 输入
- I 事务隔离:update写入流程
- 从最新版本中获取需要update的分区
- 乐观锁先把该写入的文件全部落盘,然后写json
- 发现版本号没区别,写新版本
- 发现版本号增加,先看新增版本有没有更新我需要更新的分区
- 没有,直接写新版本
- 有,两者更新同一分区,重新update
2.4 schema evolution
- Add/Drop/Rename
- 用户不直接读取parquet文件本身,而是通过数据湖接口读取
- 数据湖内部会读取应该读的parquet,并在schema上进一步处理
- ID将data与metadata列名一一对应
- 唯一确定id,新列新id,删除不复用
- 写入数据时id也写入
- 读取时用id做映射
- data没有 metadata有:add
- data有 metadata没有:drop
- data和metadata都有,但name不同:rename
- 同一列名,id不同 先删再加
3.各有所长
3.1 IceBerg
- 用户体验
- schema
- partition
- hidden
- time travel
- version rollback
3.1.1 Well-designed metadata layer
- metadata files定义了表结构,存储snapshot信息、分区列信息等
- manifest list存储一个snapshot中所有manifest信息
- manifest存储data file信息
- data files是具体文件
3.1.2 data file filter
- manifest file记录每个data file分区范围
- manifest list记录每个manifest file分区范围;分区可以快速被定位,可以做manifest list级别裁剪
- manifest file 记录每个data file每列最大值,最小值可以通过其他列做data file级别裁剪
3.1.3 hidden partition
- 传统:date列按date分区,若需要hour分区则需要新增hourlie
- IceBerg
- 数据中包含timestamp列,设置好partition transform方式
- 设置为date,转化为date;设置为hour,转化为hour
- IceBerg记录了转化关系,并按需进行partition evolution
3.2 hudi
- Hadoop Upsert Delete and Incremental
- timeline service:记录信息类似于metadata
- hudi table type
- upserts:每条样本有一个主键OK,当upsert一条数据时如果现有已有PK,则update,否则insert
- incremental
- copy on write
- merge on read:更新值写在单独文件里,读取时一起读以PK为key join
- 索引表
3.3 delta lake工作重点
- ACID
- schema 校验
- 流批一体
- 可以写入统一table
- z-order优化
3.4 异同
- ACID都支持
- partition evo:ICEBERG
- schema evo:ICEBERG hidi 不支持删 DL只能加
- timetravel都支持
4.总结场景
- 短期:每个项目都有自己的功能
- upserts hudi最好
- 可扩展性:iceberg
- z-order优化:DL
- 长期:数据湖取代Hive成为HDFS的表格式标准必然
- feature哪个最稳定
- 哪个用最简单接入最完善
- 哪个有计算引擎和社区支持
- 哪个版本管理最好
三、个人总结
本节课从理论层面介绍了数据湖与数据仓库的内容,并进一步介绍了三种不同湖仓一体实现的优势和适用场景。