这是我参与「第四届青训营 」笔记创作活动的第8天
本次学习主要是针对数据湖的三个主要开源的组件,以及数据湖与数据仓的对比及其其他相关知识的学习。
数据湖相比传统数仓而言,最明显的便是优秀的T+0能力,这个解决了Hadoop时代数据分析的顽疾。传统的数据处理流程从数据入库到数据处理通常需要一个较长的环节、涉及许多复杂的逻辑来保证数据的一致性,由于架构的复杂性使得整个流水线具有明显的延迟。
Iceberg
官网对于Iceberg的定义是一个通用的表格式(数据组织格式),提高性能的读写和元数据管理功能。Iceberg的ACID能力可以简化整个流水线的设计,传统Hive/Spark在修正数据时需要将数据读取出来,修改后再写入,有极大的修正成本。
- 统一数据存储,无缝衔接计算引擎和数据存储
Iceberg提供了基于流式的增量计算模型和基于批处理的全量表计算模型。批处理和流任务可以使用相同的存储模型,数据不再孤立;Iceberg 支持隐藏分区和分区进化,方便业务进行数据分区策略更新。 Iceberg屏蔽了底层数据存储格式的差异,提供对于Parquet,ORC和Avro格式的支持。将上层引擎的能力传导到下层的存储格式。
- 开放架构设计,开发维护成本相对可控
Iceberg 的架构和实现并未绑定于某一特定引擎,它实现了通用的数据组织格式,利用此格式可以方便地与不同引擎对接,目前 Iceberg 支持的计算引擎有 Spark、Flink、Presto 以及 Hive。 相比于 Hudi、Delta Lake,Iceberg 的架构实现更为优雅,同时对于数据格式、类型系统有完备的定义和可进化的设计; 面向对象存储的优化。Iceberg 在数据组织方式上充分考虑了对象存储的特性,避免耗时的 listing 和 rename 操作,使其在基于对象存储的数据湖架构适配上更有优势。
Hudi
Apache Hudi是一种数据湖的存储形式,在Hadoop文件系统之上提供了更新数据和删除数据的能力以及消费变化的能力。
Hudi支持如下两种表类型:
- Copy On Write
使用Parquet格式存储数据。Copy On Write表的更新操作需要通过重写实现。
- Merge On Read
使用列式文件格式(Parquet)和行式文件格式(Avro)混合的方式来存储数据。Merge On Read使用列式格式存放Base数据,同时使用行式格式存放增量数据。最新写入的增量数据存放至行式文件中,根据可配置的策略执行COMPACTION操作合并增量数据至列式文件中。
Delta Lake
Delta Lake是Spark计算框架和存储系统之间带有Schema信息数据的存储中间层。它给Spark带来了三个最主要的功能:
第一,Delta Lake使得Spark能支持数据更新和删除功能;
第二,Delta Lake使得Spark能支持事务;
第三,支持数据版本管理,运行用户查询历史数据快照。
核心特性
- ACID事务:为数据湖提供ACID事务,确保在多个数据管道并发读写数据时,数据能保持完整性。
- 数据版本管理和时间旅行:提供了数据快照,使开发人员能够访问和还原早期版本的数据以进行审核、回滚或重现实验
- 可伸缩的元数据管理:存储表或者文件的元数据信息,并且把元数据也作为数据处理,元数据与数据的对应关系存放在事务日志中;
- 流和批统一处理:Delta中的表既有批量的,也有流式和sink的;
- 数据操作审计:事务日志记录对数据所做的每个更改的详细信息,提供对更改的完整审计跟踪;
- Schema管理功能:提供自动验证写入数据的Schema与表的Schema是否兼容的能力,并提供显示增加列和自动更新Schema的能力;
- 数据表操作(类似于传统数据库的SQL):合并、更新和删除等,提供完全兼容Spark的Java/scala API;
- 统一格式:Delta中所有的数据和元数据都存储为Apache Parquet。
总结
三个引擎的初衷场景并不完全相同,Hudi 为了incremental 的 upserts,Iceberg 定位于性能的分析与可靠的数据管理,Delta 定位于流批一体的数据处理。这种场景的不同也造成了三者在设计上的差别。尤其是 Hudi,其设计与另外两个相差别更为明显。
Delta、Hudi、Iceberg三个开源项中,Delta和Hudi跟Spark的代码深度绑定,尤其是写路径。这两个项设计之初,都基本上把Spark作为他们的默认计算引擎了。 Apache Iceberg的宗旨就是要做一个通用化设计的Table Format。
参考资料