HDFS——分布式存储系统:
HDFS通过将文件分块来存储大文件,HDFS 的组件有NameNode和DataNode,分别负责提供元数
据和数据服务。在读/写数据时,HDFS客户端需要先从NameNode上获取数据读取/写入的
DataNode地址,然后和DataNode交互来完成数据读/写。
Parquet——高性能列式存储:
过滤下推到存储侧,更好地压缩性能。
数据湖发展历史
Hadoop
数据湖最开始的概念——分布式存储HDFS
使用目录来区分不同的数据集
好处:同一公司/组织可以使用共享存储;数据访问方便,灵活性高
坏处:
- 没有记录文件的schema (包括列名、列类型), 经常使用Schema on Query的方式
- 难以得知数据集包含了那些文件,是通过什么样的分区组织的
- 如果多个程序都在修改这个数据集(修改数据、修改表结构),其他程序难以配合做修改
Hive
数据湖的演进——Hive Metastore
对数据湖中的数据集进行集中“定义”:
- 数据湖中存在了哪些数据集
- 它们都存储在什么目录
- 数据集的schema是什么样子的
- 数据集有哪些分区,每个分区的目录是什么
湖仓一体
湖仓一体(数据湖的现状):
- 结合了数据湖和数据仓库的优势
- 将数据仓库中对于数据的严格管理直接实现到了低成本的分布式存储之上
数据仓库
- 数据仓库将数据从数据源提取和转换,加载到目的地
- 数据仓库存储+计算不分离
- 数据仓库严格控制写入数据的schema
数据湖是一个集中式存储库,允许您以任意规模存储所有结构化和非结构化数据。您可以按原样存储数据(无需先对数据进行结构化处理),并运行不同类型的分析 – 从控制面板和可视化到大数据处理、实时分析和机器学习,以指导做出更好的决策。
数据湖核心技术
文件结构
写入数据湖时
- 按照每条数据的date进行分区
- 额外使用metadata文件记录表信息
Time travel
👇要点:
- 每次写入都生成一个新的元数据文件,记录变更
- 分区数据在Update时,不要删除旧数据,保证新旧共存
- 元数据中存储具体的文件路径,而不仅仅是分区文件夹
👇操作步骤:
- 每次写入操作,创建一个新的json文件,以递增版本号命名,记录本次新增/删除的文件。
- 每当产生N个json,做一次聚合, 记录完整的分区文件信息
- 用checkpoint记录上次做聚合的版本号
ACID
- Atomicity:原子性-本次写入要么对用户可见,要么不可见(需要设计)
- Consistency:一致性-输入是什么,落盘的就是什么(由计算引擎保证)
- lsolation:事务隔离-正确解决读写冲突和写写冲突(需要设计)
- Durability:持久性-落完数据后,即便服务器重启结果不变(由存储引擎保证)
Schema Evolution
重要:
- 用户并不直接读取parquet文件本身,而是通过数据湖接口读取,如Dataset ds=simpleDataLake.read(mytable).option(date=2020 01-01)
- 数据湖内部会读取应该读的parquet, 并在schema 上做进步处理
三种数据湖
Iceberg工作重点
- 用户体验
- Schema evolution
- Partition evolution
- Hidden partition
- Time Travel
- Version Rollback
- 性能
- 快速file plan
- 更多的filter方式
- 可靠性
- ACID Transaction
- 完全开源,由Apache孵化开发
Hudi工作重点
- Timeline service:
Hudi管理transaction的方式
- Hudi Table Type: Copy on Write / Merge on Read
- 高效的Upserts: update
or insert
- 索引表:快速定位一条数据的位置
- Streaming Ingestion Service
- 完全开源,由Apache孵化
Delta Lake工作重点
- ACID Transaction
- Schema 校验(不是evolution)
- 流批一体
- Time Travel
- Upsert/Delete
- Z-Order 优化
- 只开源了一部分,由Databricks自己主导开发,Z-order 等优化的实现未开源
自我思考
对于三种数据湖的选择
Delta其实能够说是databricks的,本质上是为了更好地壮大Spark生态,在delta上其余的计算引擎难以替换Spark的位置,尤为是写入路径层面。
Iceberg扩展到新的计算引擎或者文件系统都很是的方便,功能相对低一点,目前最缺的功能就是 upsert 和 compaction 两个,Iceberg 社区正在以最高优先级推进这两个功能的实现。
Hudi 的状况要相对不同,若是要接入 Flink 做为 Sink 的话,须要从底向上翻一遍,把接口抽象出来,同时还要考虑不影响其余功能,固然 Hudi 的功能仍是比较完善的。