这是我参与「第四届青训营 」笔记创作活动的第7天
1 数据湖的发展阶段
1.1 数据湖的概念
源于分布式文件系统HDFS,使用目录来区分不同的数据集。
1.2 数据湖1.0阶段——Hadoop
主要是Hadoop中的分布式存储系统HDFS。
好处:
- 同一公司或组织可以共享存储内容
- 数据访问方便,灵活
坏处(数据沼泽):
- 没有记录文件的schema,经常使用Schema on Query的方式
- 无法掌握数据集中包含哪些文件以及文件的组织形式
- 如果多个程序都在修改这个数据集,其他程序难以配合做修改
1.3 数据湖2.0阶段——Hive
Hive在HDFS的基础上增加了MetaStore,对数据湖中的数据集进行了集中“定义”
- 数据湖中存放了哪些数据集
- 数据集存储在哪些目录下
- 数据集的Schema是什么样的
- 数据集是如何分区的,每个分区的目录是什么样的
缺点:
- Hive不支持Transaction事务,无法做到ACID
- Hive不支持对已存在的表进行增加/删除列操作,只能删除从新生成
1.4 数据湖3.0阶段——湖仓一体
数据仓库:
- 数据仓库是对数据源进行ETL操作,并用于类似BI的业务中
- 数据仓库是存储和计算不分离的
- 数据仓库严格控制写入数据的Schema
数据湖:
- 结合了数据仓库的优势
- 将数据仓库中对于数据的严格管理直接实现到了低成本的分布式存储之上
- 支持Transaction ACID + Schema 管理 + 存算分离 + 支持多种文件格式 + 支持多种计算引擎
| 数据仓库 | 数据湖 | |
|---|---|---|
| 成本 | 高 | 低 |
| 存储计算分离 | 否 | 是 |
| ACID | 是 | 否 |
1.5 业界三大数据湖
| 名称 | 开源公司 | 时间 |
|---|---|---|
| HUDI | Uber | 2016 |
| ICEBERG | NETFLIX | 2018 |
| DELTA LAKE | Databricks(Spark母公司) | 2019 |
2 核心技术
2.1 文件结构
写入数据湖时:
- 按照每条数据的date进行分区
- 额外使用Metadata文件记录Schema信息
2.2 Time travel
- 每次写入都生成一个新的元数据文件,记录变更信息
- 分区数据在update时,不要删除旧数据,保证新旧数据共存
- 元数据中存储具体的文件路径,而不仅仅是区分文件夹
每次写入时,创建一个新的以递增版本号命名的json文件,记录本次新增/删除的文件; 每当产生N个json,做一次聚合,记录完整的分区文件信息; 用checkpoint记录上次做聚合的版本号
2.3 Transaction
ACID 是指数据库在写入或者更新资料的过程中,为保证事务的正确可靠,所必须具备的四个特性。
数据库中的ACID:
- Atomicity:原子性,A-10 B+10,要么都做,要么都不做
- Consistency:一致性,不可以A-10 B+5
- Isolation:事务隔离,A和C同时给B转10块,B最终收到20
- Durability:永久性——转账服务器重启结果不变
数据湖中的ACID:
- Atomicity:原子性,本次写入要么对用户可见,要么不可见(需要设计)
- Consistency:一致性,输入是什么,落盘的就是什么(由计算引擎保证)
- Isolation:事务隔离,正确解决读写冲突和写写冲突(需要设计)
- Durability:永久性,落完数据后,即便服务器重启结果不变(由存储引擎保证)
2.3.1 Atomicity 原子性
写入流程:
- 写入parquet文件
- 写入json元数据文件
如何保证原子性(从用户可见性入手):
- 用户只会读取以版本号数字命名的json文件,每次都读取到最大版本号作为数据集的现状
- 新的写入写完parquet后开始写json文件,使用hash值对json文件命名,如a2fs4hfg8ee.json
- 直到json文件内容写入完毕,利用hdfs的renameIfAbsent能力将文件名称替换为000006.json,至此commit完成功能。
2.3.2 Isolation 事务隔离
| 写写冲突 | Insert | Update/Delete |
|---|---|---|
| insert | Can not conflict | |
| update/delete | Can conflict | Can conflict |
update流程:
- 从最新版本号中,获取需要update的分区
- 乐观锁先把该写入的文件全部落盘,然后进行写入json阶段
- 分情况讨论
- 1.发现版本号和一开始没区别,直接写新的版本
- 2.发现版本号增加了,看新增的这些版本是否更新我要更新的分区?没有->直接写版本;有->两者都更新了同一分区,重新update。
2.4 Schema Evolution
ID将data和metadata的列名进行一一对应
1.唯一确定的ID,新增列赋予新ID,删列ID不复用
2.写入数据时,ID也写入数据文件
3.读取数据时,用ID做映射,如果
- Data中没有,metadata中有:ADD
- Data中有,metadata棕没有:DROP
- Data和metadata中都有的同一ID,但name不同:RENAME