九、湖仓一体
2020年,大数据DataBricks公司首次提出了湖仓一体(Data Lakehouse)概念,希望将数据湖和数据仓库技术合而为一,此概念一出各路云厂商纷纷跟进。
Data Lakehouse(湖仓一体)是新出现的一种数据架构,它同时吸收了数据仓库和数据湖的优势,数据分析师和数据科学家可以在同一个数据存储中对数据进行操作,同时它也能为公司进行数据治理带来更多的便利性。
1) 目前数据存储的方案
一直以来,我们都在使用两种数据存储方式来架构数据:
- 数据仓库:主要存储的是以关系型数据库组织起来的结构化数据。数据通过转换、整合以及清理,并导入到目标表中。在数仓中,数据存储的结构与其定义的schema是强匹配的。
- 数据湖:存储任何类型的数据,包括像图片、文档这样的非结构化数据。数据湖通常更大,其存储成本也更为廉价。存储其中的数据不需要满足特定的schema,数据湖也不会尝试去将特定的schema施行其上。相反的是,数据的拥有者通常会在读取数据的时候解析schema(schema-on-read),当处理相应的数据时,将转换施加其上。
现在许多的公司往往同时会搭建数仓、数据湖这两种存储架构,一个大的数仓和多个小的数据湖。这样,数据在这两种存储中就会有一定的冗余。
2) Data Lakehouse(湖仓一体)
Data Lakehouse的出现试图去融合数仓和数据湖这两者之间的差异,通过将数仓构建在数据湖上,使得存储变得更为廉价和弹性,同时lakehouse能够有效地提升数据质量,减小数据冗余。在lakehouse的构建中,ETL起了非常重要的作用,它能够将未经规整的数据湖层数据转换成数仓层结构化的数据。
下面详细解释下:
湖仓一体(Data Lakehouse):
依据DataBricks公司对Lakehouse 的定义:一种结合了数据湖和数据仓库优势的新范式,解决了数据湖的局限性。Lakehouse 使用新的系统设计:直接在用于数据湖的低成本存储上实现与数据仓库中类似的数据结构和数据管理功能。
解释拓展:
湖仓一体,简单理解就是把面向企业的数据仓库技术与数据湖存储技术相结合,为企业提供一个统一的、可共享的数据底座。
避免传统的数据湖、数据仓库之间的数据移动,将原始数据、加工清洗数据、模型化数据,共同存储于一体化的“湖仓”中,既能面向业务实现高并发、精准化、高性能的历史数据、实时数据的查询服务,又能承载分析报表、批处理、数据挖掘等分析型业务。
湖仓一体方案的出现,帮助企业构建起全新的、融合的数据平台。通过对机器学习和AI算法的支持,实现数据湖+数据仓库的闭环,提升业务的效率。数据湖和数据仓库的能力充分结合,形成互补,同时对接上层多样化的计算生态。
十、目前有哪些开源数据湖组件
目前开源的数据湖有江湖人称“数据湖三剑客”的Hudi、Delta Lake和IceBerg。
1) Hudi
Apache Hudi是一种数据湖的存储格式,在Hadoop文件系统之上提供了更新数据和删除数据的能力以及消费变化数据的能力。
Hudi支持如下两种表类型:
- Copy On Write
使用Parquet格式存储数据。Copy On Write表的更新操作需要通过重写实现。
- Merge On Read
使用列式文件格式(Parquet)和行式文件格式(Avro)混合的方式来存储数据。Merge On Read使用列式格式存放Base数据,同时使用行式格式存放增量数据。最新写入的增量数据存放至行式文件中,根据可配置的策略执行COMPACTION操作合并增量数据至列式文件中。
应用场景
- 近实时数据摄取
Hudi支持插入、更新和删除数据的能力。可以实时摄取消息队列(Kafka)和日志服务SLS等日志数据至Hudi中,同时也支持实时同步数据库Binlog产生的变更数据。
Hudi优化了数据写入过程中产生的小文件。因此,相比其他传统的文件格式,Hudi对HDFS文件系统更加的友好。
- 近实时数据分析
Hudi支持多种数据分析引擎,包括Hive、Spark、Presto和Impala。Hudi作为一种文件格式,不需要依赖额外的服务进程,在使用上也更加的轻量化。
- 增量数据处理
Hudi支持Incremental Query查询类型,可以通过Spark Streaming查询给定COMMIT后发生变更的数据。Hudi提供了一种消费HDFS变化数据的能力,可以用来优化现有的系统架构。
2) 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。
3) IceBerg
Iceberg官网定义:Iceberg是一个通用的表格式(数据组织格式),它可以适配Presto,Spark等引擎提供高性能的读写和元数据管理功能。
数据湖相比传统数仓而言,最明显的便是优秀的T+0能力,这个解决了Hadoop时代数据分析的顽疾。传统的数据处理流程从数据入库到数据处理通常需要一个较长的环节、涉及许多复杂的逻辑来保证数据的一致性,由于架构的复杂性使得整个流水线具有明显的延迟。
Iceberg 的 ACID 能力可以简化整个流水线的设计,降低整个流水线的延迟。降低数据修正的成本。传统 Hive/Spark 在修正数据时需要将数据读取出来,修改后再写入,有极大的修正成本。Iceberg 所具有的修改、删除能力能够有效地降低开销,提升效率。
- ACID能力,无缝贴合流批一体数据存储最后一块版图
随着flink等技术的不断发展,流批一体生态不断完善,但在流批一体数据存储方面一直是个空白,直到Iceberg等数据湖技术的出现,这片空白被慢慢填补。
Iceberg 提供 ACID 事务能力,上游数据写入即可见,不影响当前数据处理任务,这大大简化了 ETL;
Iceberg 提供了 upsert、merge into 能力,可以极大地缩小数据入库延迟;
- 统一数据存储,无缝衔接计算引擎和数据存储
Iceberg提供了基于流式的增量计算模型和基于批处理的全量表计算模型。批处理和流任务可以使用相同的存储模型,数据不再孤立;Iceberg 支持隐藏分区和分区进化,方便业务进行数据分区策略更新。
Iceberg屏蔽了底层数据存储格式的差异,提供对于Parquet,ORC和Avro格式的支持。Iceberg起到了中间桥梁的能力,将上层引擎的能力传导到下层的存储格式。
- 开放架构设计,开发维护成本相对可控
Iceberg 的架构和实现并未绑定于某一特定引擎,它实现了通用的数据组织格式,利用此格式可以方便地与不同引擎对接,目前 Iceberg 支持的计算引擎有 Spark、Flink、Presto 以及 Hive。
相比于 Hudi、Delta Lake,Iceberg 的架构实现更为优雅,同时对于数据格式、类型系统有完备的定义和可进化的设计;面向对象存储的优化。Iceberg 在数据组织方式上充分考虑了对象存储的特性,避免耗时的 listing 和 rename 操作,使其在基于对象存储的数据湖架构适配上更有优势。
- 增量数据读取,实时计算的一把利剑
Iceberg 支持通过流式方式读取增量数据,支持 Structed Streaming 以及 Flink table Source。
十一、三大数据湖组件对比
1) 概览
Delta lake
由于Apache Spark在商业化上取得巨⼤成功,所以由其背后商业公司Databricks推出的Delta lake也显得格外亮眼。在没有delta数据湖之前,Databricks的客户⼀般会采⽤经典的lambda架构来构建他们的流批处理场景。
Hudi
Apache Hudi是由Uber的⼯程师为满⾜其内部数据分析的需求⽽设计的数据湖项⽬,它提供的fast upsert/delete以及compaction等功能可以说是精准命中⼴⼤⼈民群众的痛点,加上项⽬各成员积极地社区建设,包括技术细节分享、国内社区推⼴等等,也在逐步地吸引潜在⽤户的⽬光。
Iceberg
Netflix的数据湖原先是借助Hive来构建,但发现Hive在设计上的诸多缺陷之后,开始转为⾃研Iceberg,并最终演化成Apache下⼀个⾼度抽象通⽤的开源数据湖⽅案。
Apache Iceberg⽬前看则会显得相对平庸⼀些,简单说社区关注度暂时⽐不上delta,功能也不如Hudi丰富,但却是⼀个野⼼勃勃的项⽬,因为它具有⾼度抽象和⾮常优雅的设计,为成为⼀个通⽤的数据湖⽅案奠定了良好基础。
2) 共同点
三者均为Data Lake的数据存储中间层,其数据管理的功能均是基于⼀系列的meta⽂件。
Meta⽂件的⾓⾊类似于数据库的catalog\wal,起到schema管理、事务管理和数据管理的功能。与数据库不同的是,这些meta⽂件是与数据⽂件⼀起存放在存储引擎中的,⽤户可以直接看到。这个做法直接继承了⼤数据分析中数据对⽤户可见的传统,但是⽆形中也增加了数据被不⼩⼼破坏的风险。⼀旦删了meta⽬录,表就被破坏了,恢复难度很⼤。
Meta包含有表的schema信息。因此系统可以⾃⼰掌握schema的变动,提供schema演化的⽀持。Meta⽂件也有transaction log的功能(需要⽂件系统有原⼦性和⼀致性的⽀持)。
所有对表的变更都会⽣成⼀份新的meta⽂件,于是系统就有了ACID和多版本的⽀持,同时可以提供访问历史的功能。在这些⽅⾯,三者是相同的。
3) 关于Hudi
Hudi 的设计⽬标正如其名,Hadoop Upserts Deletes and Incrementals(原为 Hadoop Upserts anD Incrementals),强调了其主要⽀持Upserts、Deletes 和 Incremental 数据处理,其主要提供的写⼊⼯具是 Spark HudiDataSource API 和⾃⾝提供的 HoodieDeltaStreamer,均⽀持三种数据写⼊⽅式:UPSERT,INSERT 和 BULK_INSERT。其对 Delete 的⽀持也是通过写⼊时指定⼀定的选项⽀持的,并不⽀持纯粹的 delete 接⼝。
在查询⽅⾯,Hudi ⽀持 Hive、Spark、Presto。
在性能⽅⾯,Hudi 设计了 HoodieKey ,⼀个类似于主键的东西。对于查询性能,⼀般需求是根据查询谓词⽣成过滤条件下推⾄datasource。Hudi 这⽅⾯没怎么做⼯作,其性能完全基于引擎⾃带的谓词下推和 partition prune 功能。
Hudi 的另⼀⼤特⾊是⽀持 Copy On Write 和 Merge On Read。前者在写⼊时做数据的 merge,写⼊性能略差,但是读性能更⾼⼀些。后者读的时候做 merge,读性能差,但是写⼊数据会⽐较及时,因⽽后者可以提供近实时的数据分析能⼒。最后,Hudi 提供了⼀个名为run_sync_tool 的脚本同步数据的 schema 到 Hive 表。Hudi 还提供了⼀个命令⾏⼯具⽤于管理 Hudi 表。
4) 关于Iceberg
Iceberg 没有类似的 HoodieKey 设计,其不强调主键。没有主键,做 update/delete/merge 等操作就要通过 Join 来实现,⽽ Join 需要有⼀个类似 SQL 的执⾏引擎。
Iceberg 在查询性能⽅⾯做了⼤量的⼯作。值得⼀提的是它的 hidden partition 功能。
Hidden partition 意思是说,对于⽤户输⼊的数据,⽤户可以选取其中某些列做适当的变换(Transform)形成⼀个新的列作为 partition 列。这个 partition 列仅仅为了将数据进⾏分区,并不直接体现在表的 schema中。
5) 关于Delta
Delta 的定位是流批⼀体的 Data Lake 存储层,⽀持 update/delete/merge。由于出⾃ Databricks,spark 的所有数据写⼊⽅式,包括基于dataframe 的批式、流式,以及 SQL 的 Insert、Insert Overwrite 等都是⽀持的(开源的 SQL 写暂不⽀持,EMR 做了⽀持)。不强调主键,因此其 update/delete/merge 的实现均是基于 spark 的 join 功能。在数据写⼊⽅⾯,Delta 与 Spark 是强绑定的,这⼀点 Hudi 是不同的:Hudi 的数据写⼊不绑定 Spark(可以⽤ Spark,也可以使⽤ Hudi ⾃⼰的写⼊⼯具写⼊)。
在查询⽅⾯,开源 Delta ⽬前⽀持 Spark 与 Presto,但是,Spark 是不可或缺的,因为 delta log 的处理需要⽤到 Spark。这意味着如果要⽤ Presto 查询 Delta,查询时还要跑⼀个 Spark 作业。更为难受的是,Presto 查询是基于 SymlinkTextInputFormat 。在查询之前,要运⾏ Spark 作业⽣成这么个 Symlink ⽂件。如果表数据是实时更新的,意味着每次在查询之前先要跑⼀个 SparkSQL,再跑 Presto。为此,EMR 在这⽅⾯做了改进可以不必事先启动⼀个 Spark 任务。
在查询性能⽅⾯,开源的 Delta ⼏乎没有任何优化。
Delta 在数据 merge ⽅⾯性能不如 Hudi,在查询⽅⾯性能不如 Iceberg,是不是意味着 Delta ⼀⽆是处了呢?其实不然。Delta 的⼀⼤优点就是与 Spark 的整合能⼒,尤其是其流批⼀体的设计,配合 multi-hop 的 data pipeline,可以⽀持分析、Machine learning、CDC 等多种场景。使⽤灵活、场景⽀持完善是它相⽐ Hudi 和 Iceberg 的最⼤优点。另外,Delta 号称是 Lambda 架构、Kappa 架构的改进版,⽆需关⼼流批,⽆需关⼼架构。这⼀点上 Hudi 和 Iceberg 是⼒所不及的。
6) 总结
三个引擎的初衷场景并不完全相同,Hudi 为了 incremental 的 upserts,Iceberg 定位于⾼性能的分析与可靠的数据管理,Delta 定位于流批⼀体的数据处理。这种场景的不同也造成了三者在设计上的差别。尤其是 Hudi,其设计与另外两个相⽐差别更为明显。因此后⾯是趋同还筑起各⾃专长优势壁垒未可知。
Delta、Hudi、Iceberg三个开源项⽬中,Delta和Hudi跟Spark的代码深度绑定,尤其是写⼊路径。这两个项⽬设计之初,都基本上把Spark作为他们的默认计算引擎了。⽽Apache Iceberg的⽅向⾮常坚定,宗旨就是要做⼀个通⽤化设计的Table Format。
它完美的解耦了计算引擎和底下的存储系统,便于多样化计算引擎和⽂件格式,很好的完成了数据湖架构中的Table Format这⼀层的实现,因此也更容易成为Table Format层的开源事实标准。
另⼀⽅⾯,Apache Iceberg也在朝着流批⼀体的数据存储层发展,manifest和snapshot的设计,有效地隔离不同transaction的变更,⾮常⽅便批处理和增量计算。并且,Apache Flink已经是⼀个流批⼀体的计算引擎,⼆者都可以完美匹配,合⼒打造流批⼀体的数据湖架构。
Apache Iceberg这个项⽬背后的社区资源⾮常丰富。在国外,Netflix、Apple、Linkedin、Adobe等公司都有PB级别的⽣产数据运⾏在Apache Iceberg上;在国内,腾讯这样的巨头也有⾮常庞⼤的数据跑在Apache Iceberg之上,最⼤的业务每天有⼏⼗T的增量数据写⼊。