这是我参与「第四届青训营」笔记创作活动的第 12 天。
一、笔记内容
1. 发展历史
2. 核心技术
3. 各有所长
4. 直接场景
二、发展历史
1.数据湖发展阶段
graph TD
Hadoop --> Hive --> 湖仓一体
1.Hadoop
数据湖最开始的概念——分布式存储HDFS
使用目录来区分不同的数据集
好处:
-
同一公司/组织可以使用共享存储
-
数据访问方便,灵活性高
缺点:
1.没有记录文件的schema(包括列名、列类型),经常使用Schema on Query的方式;
2.难以得知数据集包含了那些文件,是通过什么样的分区组织的;
3.如果多个程序都在修改这个数据集(修改数据、修改表结构),其他程序难以配合做修改;
容易陷入数据沼泽!
2.Hive
数据湖的演进——Hive Metastore
对数据湖中的数据集进行集中“定义”
-
数据湖中存在了哪些数据集;
-
它们都存储在什么目录;
-
数据集的schema是什么样子的;
-
数据集有哪些分区,每个分区的目录是什么。
缺点:
-
没有实现Transaction ACID。
-
没有支持更多样的schema变更。
3.湖仓一体
数据仓库:数据仓库将数据从数据源提取和转换,加载到目的地。
-
数据仓库存储 + 计算不分离;
-
数据仓库严格控制写入数据的schema。
| 数据仓库 | 数据湖(阶段2) | |
|---|---|---|
| 成本 | 高 | 低 |
| 存储计算分离 | 否 | 是 |
| ACID | 是 | 否 |
湖仓一体(数据湖的现状):
-
结合了数据湖和数据仓库的优势;
-
将数据仓库中对于数据的严格管理直接实现到了低成本的分布式存储之上;
-
Key Features:
-
Transaction ACID
-
Schema管理
-
存储计算分离
-
支持多种计算引擎和文件格式
2.业界三大数据湖
-
Hudi : 最初希望解决的问题是使数据写入能够更低延迟。
-
lceberg : 最初希望解决的问题是拜托Hive架构带来的问题。
-
Delta Lake
三、核心技术
1.文件结构
写入数据湖时
1按照每条数据的date进行分区;
2.额外使用metadata文件记录表信息。
2.Time travel
要点:
1.每次写入都生成一个新的元数据文件,记录变更;
2.分区数据在Update时,不要删除旧数据,保证新旧共存;
3.元数据中存储具体的文件路径,而不仅仅是分区文件夹。
实现:
1.每一次写入操作,创建一个新的json文件,以递增版本号命名,记录本次新增/删除的文件。
2.每当产生N个json,做一次聚合,记录完整的分区文件信息。
3.用checkpoint记录上次做聚合的版本号。
3.Transaction
ACID: 指数据库在写入或更新资料的过程中,为保证事务是正确可靠的,所必须具备的四个特性。
1. Atomicity:原子性
2. Consistency:一致性
3. lsolation:事务隔离
4. Durability:持久性
数据湖中的ACID:
1. Atomicity:本次写入要么对用户可见,要么不可见(需要设计)
-
写入流程
-
写入parquet数据文件
-
写入json元数据文件
-
-
确保原子性从用户可见性入手
-
用户只会读取以版本号数字命名的json文件,每次都读取到最大的版本号作为数据集的现状;
-
新的写入写完parquet后开始写json文件,使用hash值对json文件命名,如a2fs4hfg8ee.json;
-
直到json文件内容写入完毕,利用hdfs的renamelfAbsent能力将a2fs4hfg8ee.json替换为000006.json,到此为止commit完成,新的读取将会以000006.json作为最新版本。
-
-
解决读写冲突
-
新的写入除非已经commit,否则用户读不到;
-
用户正在读的分区,被另一个写入进行了更新,数据不会进行替换,而是共存。
-
2. Consistency:输入是什么,落盘的就是什么(由计算引擎保证)
3. Isolation:正确解决读写冲突和写写冲突(需要设计)
| 写写冲突 | lnsert | Update/delete |
|---|---|---|
| insert | Can not conflict | - |
| Update/delete | Can conflict | Can conflict |
Update写入流程:
-
从最新的版本中,获取需要update的分区;
-
乐观锁先把该写入的文件全落盘,然后进入写json阶段;
-
分几种情况:
-
发现版本号和开始没区别,直接写新的版本。
-
发现版本号增加了,看看新增的这些版本有没有更新我要更新的分区?
-
没有,直接写新的版本。
-
有,两者都更新了同一分区,得重新update 了。
-
-
4. Durability:落完数据后,即便服务器重启结果不变(由存储引擎保证)
4.Schema Evolution
Add/Drop/Rename
重要:
-
用户并不直接读取parquet文件本身,而是通过数据湖接口读取;
-
数据湖内部会读取应该读的parquet,并在schema上做进一步处理。
ID将data和metadata的列名做一一对应
1.唯一确定的ID。新增列赋予新ID。删列ID不复用。
2.写入数据时,ID也写入数据文件
3.读取数据时,用ID做映射,如果
-
Data中没有,metadata中有:ADD
-
Data中有,metadata中没有:DROP
-
Data和metadata中都有同一ID,但是name不同:RENAME
-
如果都有同—列名,而ID不同:先DROP后ADD
四、各有所长
1.lceberg工作重点
用户体验
1. Schema evolution
2. Partition evolution
3. Hidden partition
4. Time Travel
5. Version Rollback
性能
1.快速file plan
2.更多的filter方式
可靠性
ACID Transaction
完全开源,由Apache孵化开发
1.Well-designed Metadata Layer
(1) Metadata files定义了表结构,存储了snapshot信息,分区列信息等。
(2) Manifest lists存储了一个snapshot 中所有manifest的信息。
(3) Manifests存储了一些data files的信息。
(4) Data files就是具体的数据文件。
2.Data File Filter
一些有助于filter 的数据被层层记录,比如:
1.Manifest file记录了每个data file 的分区范围。
2.Manifest list记录了每个manifest file的分区范围,分区可以被快速定位,可以做manifest list级别裁剪。
- Manifest file记录了每个data file 每—列的最大值,最小值可以通过其他的列(Userld)做data file 级别裁剪。
3.Hidden Partition
传统的分区方式:
数据中包含了date列,则按照date分区;
如果希望按照hour分区,则需要新增hour列。
lceberg的分区方式:
数据中包含timestamp列,设置好partition transform方式
-
设置为date时,iceberg帮助转化为date分区
-
设置为hour时,iceberg帮助转化为hour 分区
blceberg记录了这层转化关系,并且按你的需要进行partition evolution。
2.Hudi
Hudi:Hadoop Upsert Delete and lncremental
Hudi工作重点:
1. Timeline service: Hudi管理transaction的方式
2. Hudi Table Type: Copy on Write /Merge on Read
3.高效的Upserts: update or insert
4.索引表:快速定位一条数据的位置
- Streaming Ingestion Service
6.完全开源,由Apache孵化
1.Timeline Serivce & Upsert & Incremental
Timeline Service:记录的信息类似于metadata;
Upsert:每条样本都有一个主键PK,当Upsert一条数据时,如果现有的数据中有这个PK,则 update这条数据。否则直接insert这条数据。
Incremental:某个时间点后新增的数据。
2.Copy on Write
问题:操作所有数据,浪费资源。
3.Merge On Read
缓解了Copy on Write中操作大量数据的问题。
3.Delta Lake
Delta Lake工作重点:
-
ACID Transaction
-
Schema校验(不是evolution)
3.流批一体
-
Time Travel
-
Upsert/Delete
-
Z-Order 优化
7.只开源了一部分,由Databricks自己主导开发,Z-order等优化的实现未开源
五、总结场景
短期来看:每个项目都有一些属于自己的功能
-
如果强需求Upserts,也许Hudi是最好的选择
-
如果希望可扩展性强,那么设计优良的lceberg是最好的选择
-
如果希望用上Z-Order等优化,那么掏钱买Databricks的企业版 Delta是不二之选
长期来看:数据湖取代 Hive,成为HDFS上的表格式标准是必然的,在选择之前问自己四个问题:
1.我需要的feature在哪个数据湖上是最稳定的
2.哪一个数据湖能够用最简单的接入方式(SQL)用上最完善的功能
3.哪一个数据湖有计算引擎侧的支持和社区的支持
4.哪一个数据湖的版本管理做的最好,最鲁棒