大数据基础:数据湖重要原理架构

文件目录

数据湖重要原理架构

一、数据湖概念

二、数据湖与数据仓库的区别

三、Hudi概念与原理

3.1、Hudi介绍

3.2、Hudi特点

3.3、Hudi术语概念

3.3.1、Timeline

3.3.2、文件格式及索引

3.3.3、表类型

Copy On Write - COW

Merge On Read - MOR

COW&MOR对比

3.3.4、查询类型

四、Iceberg概念与原理

4.1、Iceberg概念

4.2、Iceberg特点

4.3、Iceberg术语

4.4、表格式Table Format

4.5、特点详述

4.5.1、Iceberg分区与隐藏分区(Hidden Partition)

4.5.2、Iceberg表演化(Table Evolution)

4.5.3、模式演化(Schema Evolution)

4.5.4、分区演化(partition Evolution)

4.5.5、列顺序演化(Sort Order Evolution)


数据湖重要原理架构

一、数据湖概念

数据湖是一个集中式的存储库,允许你以任意规模存储多个来源、所有结构化和非结构化数据,可以按照原样存储数据,无需对数据进行结构化处理,并运行不同类型的分析对数据进行加工。

二、数据湖与数据仓库的区别

2.1、存储数据类型

  • 数据仓库是存储数据,进行建模,存储的是结构化数据。

  • 数据湖以其本源格式保存大量原始数据,包括结构化的、半结构化的和非结构化的数据,主要是由原始的、混乱的、非结构化的数据组成。在需要数据之前,没有定义数据结构和需求。

2.2、数据处理模式

在我们可以加载到数据仓库中的数据,我们首先需要定义好它,这叫做写时模式(Schema-On-Write)。而对于数据湖,您只需加载原始数据,然后,当您准备使用数据时,就给它一个定义,这叫做读时模式(Schema-On-Read)。这是两种截然不同的数据处理方法。

因为数据湖是在数据使用时再定义模型结构,因此提高了数据模型定义的灵活性,可满足更多不同上层业务的高效率分析诉求。

三、Hudi概念与原理

3.1、Hudi介绍

Apache Hudi是一个Data Lakes的开源方案,Hudi是Hadoop Updates and Incrementals的简写,它是由Uber开发并开源的Data Lakes解决方案。Hudi能够基于HDFS之上管理大型分析数据集,可以对数据进行插入、更新、增量消费等操作,主要目的是高效减少摄取过程中的数据延迟。

Hudi基于Parquet列式存储与Avro行式存储,同时避免创建小文件,实现高效率低延迟的数据访问。在HDFS数据集上提供插入更新、增量拉取、全量拉取。

3.2、Hudi特点

Hudi具有如下特点:

  • 快速upsert,可插入索引。

  • 以原子方式操作数据并具有回滚功能。

  • 写入器和查询之间的快照隔离。

  • 用于数据恢复的savepoint保存点,Hudi通过Savepoint来实现数据恢复。

  • 管理文件大小,使用统计数据布局。

  • 行和列数据的异步压缩。

3.3、Hudi术语概念

3.3.1、Timeline

Timeline 是Hudi用来管理提交(commit)的抽象,每个 commit 都绑定一个固定时间戳,分散到时间线上。在Timeline上,每个commit被抽象为一个 HoodieInstant(Hoodie瞬时时刻),一个 instant 记录了一次提交(commit)的行为、时间戳、和状态,也就是说每个HoodieInstant 包含Action、Time、State三个部分。

3.3.2、文件格式及索引

Hudi将表组织成HDFS上某个指定目录(basepath)下的目录结构,表被分成多个分区,分区是以目录的形式存在,每个目录下面会存在属于该分区的多个文件,类似Hive表,每个Hudi表分区通过一个分区路径(partitionpath)来唯一标识。

Hudi将表组织成HDFS上某个指定目录(basepath)下的目录结构,表被分成多个分区,分区是以目录的形式存在,每个目录下面会存在属于该分区的多个文件,类似Hive表,每个Hudi表分区通过一个分区路径(partitionpath)来唯一标识。

Hudi会通过记录Key与分区Path组成Hoodie Key,即Record Key+Partition Path,通过将Hoodie Key映射到前面提到的文件ID,具体其实是映射到file_group/file_id,这就是Hudi的索引。一旦记录的第一个版本被写入文件中,对应的Hoodie Key就不会再改变了。

Hudi的Base file(parquet 文件)在根目录中的”.hoodie_partition_metadata”去记录了record key组成的 BloomFilter,用于在 file based index 的实现中实现高效率的key contains检测,决定数据是新增还是更新。

3.3.3、表类型
Copy On Write - COW

Copy On Write简称COW,在数据写入的时候,复制一份原来的拷贝,在其基础上添加新数据,生成一个新的持有base file (*.parquet,对应写入的instant time)的File Slice,数据存储格式为parquet列式存储格式。用户在读取数据时,会扫描所有最新的File Slice下的base file。

如上图,每一个颜色都包含了截至到其所在时间的所有数据。老的数据副本在超过一定的个数限制后,将被删除(hoodie.cleaner.commits.retained 参数配置,保留几个历史版本,不包含最后一个版本,默认10个)。这种类型的表,没有compact instant,因为写入时相当于已经compact了。

优点:读取时只需要读取对应分区的一个数据文件即可,比较高效。

缺点:数据写入的时候,需要复制一个先前的副本再在其基础上生成新的数据文件,这个过程比较耗时,且由于耗时,读请求读取到的数据相对就会滞后。

Merge On Read - MOR

Merge On Read简称MOR,使用列式存储(parquet)和行式存储(arvo)混合的方式来存储数据。更新时写入到增量(Delta)文件中,之后通过同步或异步的COMPACTION操作,生成新版本的列式格式文件。

Merge-On-Read表存在列式格式的Base文件,也存在行式格式的增量(Delta)文件,新到达的更新都会写到增量日志文件中(log文件),根据实际情况进行COMPACTION操作来将增量文件合并到Base文件上。

通过参数”hoodie.compact.inline”来开启是否一个事务完成后执行压缩操作,默认不开启。通过参数“hoodie.compact.inline.max.delta.commits”来设置提交多少次合并log文件到新的parquet文件,默认是5次。这里注意,以上两个参数都是针对每个File Slice而言。我们同样可以控制“hoodie.cleaner.commits.retained”来保存有多少parquet文件,即控制FileSlice文件个数。

上图中,每个文件分组都对应一个增量日志文件(Delta Log File)。COMPACTION操作在后台定时执行。会把对应的增量日志文件合并到文件分组的Base文件中,生成新版本的Base文件。

对于查询10:10之后的数据的Read Optimized Query,只能查询到10:05及其之前的数据,看不到之后的数据,查询结果只包含版本为10:05、文件ID为1、2、3的文件;但是Snapshot Query是可以查询到10:05之后的数据的。

Read Optimized QuerySnapshot Query是两种不同的查询类型。

优点:由于写入数据先写delta log,且delta log较小,所以写入成本较低。

缺点:需要定期合并整理compact,否则碎片文件较多。读取性能较差,因为需要将delta log 和 老数据文件合并。

COW&MOR对比
对比点Copy On WriteMerge On Read
数据延迟每次基于上次生成新的文件-高直接写入Avro log文件-低
查询延迟列式-低列式+行式-高
更新IO每次基于上次生成新的文件-大直接写入log文件-小
文件大小单个全量使用parquet文件存储,占用空间小单个全量存储使用parquet+avro格式存储,占用空间相对大

3.3.4、查询类型
  • Snapshot Query

读取所有Partition下每个FileGroup最新的FileSlice中的文件,Copy On Write表读Base(Parquet格式)文件,Merge On Read 表读Base(Parquet格式)文件+Log(Avro)格式文件,也就是说这种查询模式是将到当前时刻所有数据都读取出来,如果有更新数据,读取的也是更新后数据,例如:MOR模式下,读取对应的Base+Log文件就是读取当前所有数据更新后的结果数据。

  • Incremental Query

无论Hudi表模式是COW或者是MOR模式,这种模式可以查询指定时间戳后的增量数据,需要由用户指定一个时间戳。

  • Read Optimized Query

这种模式只能查询列式格式Base文件中的最新数据。对于COW表模式,读取数据与Snapshot模式一样。对于MOR模式的数据,读取数据只会读取到Base文件列式数据,不会读取Log文件Avro格式数据。

四、Iceberg概念与原理

4.1、Iceberg概念

Apache Iceberg是一种用于大型数据分析场景的开放表格式(Table Format)。Iceberg使用一种类似于SQL表的高性能表格式,Iceberg格式表单表可以存储数十PB数据,适配Spark、Trino、PrestoDB、Flink和Hive等计算引擎提供高性能的读写和元数据管理功能,Iceberg是一种数据湖解决方案。

4.2、Iceberg特点

Iceberg具备以下特点:

  • Iceberg支持实时/批量数据写入和读取,支持Spark/Flink计算引擎。

  • Iceberg支持事务ACID,支持添加、删除、更新数据。

  • 不绑定任何底层存储,支持Parquet、ORC、Avro格式兼容行存储和列存储。

  • Iceberg支持隐藏分区和分区变更,方便业务进行数据分区策略。

  • Iceberg支持快照数据重复查询,具备版本回滚功能。

  • Iceberg扫描计划很快,读取表或者查询文件可以不需要分布式SQL引擎。

  • Iceberg通过表元数据来对查询进行高效过滤。

  • 基于乐观锁的并发支持,提供多线程并发写入能力并保证数据线性一致。

4.3、Iceberg术语

data files(数据文件):

数据文件是Apache Iceberg表真实存储数据的文件,一般是在表的数据存储目录的data目录下,如果我们的文件格式选择的是parquet,那么文件是以“.parquet”结尾,例如:00000-0-root_20211212192602_8036d31b-9598-4e30-8e67-ce6c39f034da-job_1639237002345_0025-00001.parquet 就是一个数据文件。

Iceberg每次更新会产生多个数据文件(data files)。

Snapshot(表快照):

快照代表一张表在某个时刻的状态。每个快照里面会列出表在某个时刻的所有 data files 列表。data files是存储在不同的manifest files里面,manifest files是存储在一个Manifest list文件里面,而一个Manifest list文件代表一个快照。

Manifest list(清单列表):

manifest list是一个元数据文件,它列出构建表快照(Snapshot)的清单(Manifest file)。这个元数据文件中存储的是Manifest file列表,每个Manifest file占据一行。每行中存储了Manifest file的路径、其存储的数据文件(data files)的分区范围,增加了几个数文件、删除了几个数据文件等信息,这些信息可以用来在查询时提供过滤,加快速度。

Manifest file(清单文件):

Manifest file也是一个元数据文件,它列出组成快照(snapshot)的数据文件(data files)的列表信息。每行都是每个数据文件的详细描述,包括数据文件的状态、文件路径、分区信息、列级别的统计信息(比如每列的最大最小值、空值数等)、文件的大小以及文件里面数据行数等信息。其中列级别的统计信息可以在扫描表数据时过滤掉不必要的文件。

Manifest file是以avro格式进行存储的,以“.avro”后缀结尾,例如:8138fce4-40f7-41d7-82a5-922274d2abba-m0.avro。

4.4、表格式Table Format

Apache Iceberg作为一款数据湖解决方案,是一种用于大型分析数据集的开放表格式(Table Format),表格式可以理解为元数据及数据文件的一种组织方式。Iceberg底层数据存储可以对接HDFS,S3文件系统,并支持多种文件格式,处于计算框架(Spark、Flink)之下,数据文件之上。

下面介绍下Iceberg底层文件组织方式,下图是Iceberg中表格式,s0、s1代表的是表Snapshot信息,每个表示当前操作的一个快照,每次commit都会生成一个快照Snapshot,每个Snapshot快照对应一个manifest list 元数据文件,每个manifest list 中包含多个Manifest元数据文件,manifest中记录了当前操作生成数据所对应的文件地址,也就是data file的地址。

基于snapshot的管理方式,Iceberg能够获取表历史版本数据、对表增量读取操作,data files存储支持不同的文件格式,目前支持parquet、ORC、Avro格式。

4.5、特点详述

4.5.1、Iceberg分区与隐藏分区(Hidden Partition)

Iceberg支持分区来加快数据查询。在Iceberg中设置分区后,可以在写入数据时将相似的行分组,在查询时加快查询速度。Iceberg中可以按照年、月、日和小时粒度划分时间戳组织分区。

在Hive中也支持分区,但是要想使分区能加快查询速度,需要在写SQL时指定对应的分区条件过滤数据,在Iceberg中写SQL查询时不需要再SQL中特别指定分区过滤条件,Iceberg会自动分区,过滤掉不需要的数据。

在Iceberg中分区信息可以被隐藏起来,Iceberg的分区字段可以通过一个字段计算出来,在建表或者修改分区策略之后,新的数据会自动计算所属于的分区,在查询的时候同样不用关心表的分区是什么字段,只需要关注业务逻辑,Iceberg会自动过滤不需要的分区数据。

正是由于Iceberg的分区信息和表数据存储目录是独立的,使得Iceberg的表分区可以被修改,而且不会涉及到数据迁移。

4.5.2、Iceberg表演化(Table Evolution)

在Hive分区表中,如果把一个按照天分区的表改成按小时分区,那么没有办法在原有表上进行修改,需要创建一个按照小时分区的表,然后把数据加载到此表中。

Iceberg支持就地表演化,可以通过SQL的方式进行表级别模式演进,例如:更改表分区布局。Iceberg进行以上操作时,代价极低,不存在读出数据重新写入或者迁移数据这种费时费力的操作。

4.5.3、模式演化(Schema Evolution)

Iceberg支持以下几种Schema的演化:

  • ADD:向表或者嵌套结构增加新列。

  • Drop:从表或嵌套结构中移除列。

  • Rename:重命名表中或者嵌套结构中的列。

  • Update:将复杂结构(Struct、Map<Key,Value>,list)中的基本类型扩展类型长度,比如:tinyint修改成int。

  • Reorder:改变列的顺序,也可以改变嵌套结构中字段的排序顺序。

注意:

Iceberg Schema的改变只是元数据的操作改变,不会涉及到重写数据文件。Map结构类型不支持Add和Drop字段。

Iceberg保证Schema演化是没有副作用的独立操作,不会涉及到重写数据文件,具体如下:

  • 增加列时不会从另一个列中读取已存在的数据。

  • 删除列或者嵌套结构中的字段时,不会改变任何其他列的值。

  • 更新列或者嵌套结构中字段时,不会改变任何其他列的值。

  • 改变列或者嵌套结构中字段顺序的时候,不会改变相关联的值。

Iceberg实现以上的原因使用唯一的id来追踪表中的每一列,当添加一个列时,会分配新的ID,因此列对应的数据不会被错误使用。

4.5.4、分区演化(partition Evolution)

Iceberg分区可以在现有表中更新,因为Iceberg查询流程并不和分区信息直接关联。

当我们改变一个表的分区策略时,对应修改分区之前的数据不会改变, 依然会采用老的分区策略, 新的数据会采用新的分区策略,也就是说同一个表会有两种分区策略, 旧数据采用旧分区策略, 新数据采用新新分区策略, 在元数据里两个分区策略相互独立,不重合。

因此,在我们写SQL进行数据查询时, 如果存在跨分区策略的情况, 则会解析成两个不同执行计划,如Iceberg官网提供图所示:

图中booking_table表2008年按月分区, 进入2009年后改为按天分区, 这两种分区策略共存于该表中。得益于Iceberg的隐藏分区(Hidden Partition), 针对上图中的SQL查询, 不需要在SQL中特别指定分区过滤条件(是按照月还是按照天), Iceberg会自动分区,过滤掉不需要的数据。

4.5.5、列顺序演化(Sort Order Evolution)

Iceberg可以在一个已经存在的表上修改排序策略。修改了排序策略之后, 旧数据依旧采用老排序策略不变。往Iceberg里写数据的计算引擎总是会选择最新的排序策略, 但是当排序的代价极其高昂的时候, 就不进行排序了。


  • 📢欢迎点赞 👍 收藏 ⭐留言 📝 如有错误敬请指正!

  • 📢本文由 Lansonli 原创,首发于 CSDN博客🙉

  • 📢停下休息的时候不要忘了别人还在奔跑,希望大家抓紧时间学习,全力奔赴更美好的生活✨

  • 31
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Lansonli

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值