Hudi-表的存储类型及比较
作者:互联网
总述
Hudi提供两类型表:写时复制(Copy on Write, COW)表和读时合并(Merge On Read, MOR)表。 对于Copy-On-Write Table,用户的update会重写数据所在的文件,所以是一个写放大很高,但是读放大为0,适合写少读多的场景。 对于Merge-On-Read Table,整体的结构有点像LSM-Tree,用户的写入先写入到delta data中,这部分数据使用行存,这部分delta data可以手动merge到存量文件中,整理为parquet的列存结构。![](https://www.icode9.com/i/l/?n=22&i=blog/1109757/202202/1109757-20220226214255117-2004016742.png)
数据计算模型
hudi是Uber主导开发的开源数据湖框架,所以大部分的出发点都来源于Uber自身场景,比如司机数据和乘客数据通过订单ID来做join等。 在hudi过去的使用场景里,和大部分公司的架构类似,采用批式和流式共存的Lambda架构,后来Uber提出增量Incremental模型,相对批式来讲,更加实时,相对流式而言,更加经济。![](https://www.icode9.com/i/l/?n=22&i=blog/1109757/202202/1109757-20220226214255281-1768485287.png)
1.批式模型(Batch)
批式模型就是使用MapReduce、Hive、Spark等典型的批计算引擎,以小时任务或者天任务的形式来做数据计算 特性 A.延迟:小时级延迟或者天级别延迟。这里的延迟不单单指的是定时任务的时间,在数据架构里,这里的延迟时间通常是定时任务间隔时间+一系列依赖任务的计算时间+数据平台最终可以展示结果的时间。数据量大、逻辑复杂的情况下,小时任务计算的数据通常真正延迟的时间是2-3小时。 B.数据完整度:数据较完整。以处理时间为例,小时级别的任务,通常计算的原始数据已经包含了小时内的所有数据,所以得到的数据相对较完整。但如果业务需求是事件时间,这里涉及到终端的一些延迟上报机制,在这里,批式计算任务就很难派上用场。 C.成本:成本很低。只有在做任务计算时,才会占用资源,如果不做任务计算,可以将这部分批式计算资源出让给在线业务使用。从另一个角度来说成本是挺高的,如原始数据做了一些增删改查,数据晚到的情况,那么批式任务是要全量重新计算。![](https://www.icode9.com/i/l/?n=22&i=blog/1109757/202202/1109757-20220226214255113-780006341.png)
2.流式模型(Stream)
流式模型,典型的就是使用Flink来进行实时的数据计算 特性 A.延迟:很短,甚至是实时。 B.数据完整度:较差。因为流式引擎不会等到所有数据到齐之后再开始计算,所以有一个watermark的概念,当数据的时间小于watermark时,就会被丢弃,这样是无法对数据完整度有一个绝对的保障。在互联网场景中,流式模型主要用于活动时的数据大盘展示,对数据的完整度要求并不算很高。在大部分场景中,用户需要开发两个程序,一是流式数据生产流式结果,而是批式计算人物,用于次日修复实时结果 C.成本:很高。因为流式任务时常驻的,并且对于多流join的场景,通常要借助内存或者数据库来做state的存储,不管是序列化开销,还是和外部组件交互产生的额外IO,在大数据量下都是不容忽视的。![](https://www.icode9.com/i/l/?n=22&i=blog/1109757/202202/1109757-20220226214255218-1735520580.png)
3.增量模型(Incremental)
针对批式和流式的优缺点,Uber提出了增量模型(Incremental Mode),相对批式来讲,更加实时;相对流式而言,更加经济。![](https://www.icode9.com/i/l/?n=22&i=blog/1109757/202202/1109757-20220226214255199-710134592.png)
查询类型(Query Type)
Hudi支持三种不同的查询表的方式:Snapshot Queries(快照查询)、Incremental Queries(增量查询)和Read Optimized Queries(读优化查询).![](https://www.icode9.com/i/l/?n=22&i=blog/1109757/202202/1109757-20220226214255242-804414218.png)
1.Snapshot Queries(快照查询)
查询某个增量提交操作中数据集的最新快照,先进行动态合并最新的基本文件(parquet)和增量文件(Avro)来提供近实时数据集(通常会存在几分钟的延迟) 读取所有partition下每个FileGroup最新的FileSlice中的文件,Copy On Write表读parquet文件,Merge On Read表读parquet + log文件![](https://www.icode9.com/i/l/?n=22&i=blog/1109757/202202/1109757-20220226214255303-1006108354.png)
2.Incremental Queries(增量查询)
仅查询新写入数据集的文件,需要指定一个Commit/Compaction的即时时间(位于Timeline上的某个instant)作为条件,来查询此条件之后的新数据 可查看自给定commit/delta commit即时操作依赖新写入的数据,有效地提供变更流来启用增量数据管道![](https://www.icode9.com/i/l/?n=22&i=blog/1109757/202202/1109757-20220226214255157-1618748526.png)
3.Read Optimized Queries(读优化查询)
直接查询基本文件(数据集的最新快照),其实就是列式文件(Parquet)。并保证与非hudi列式数据集相比,具有相同的列式查询性能 可查看给定的commit/compact即时操作的表的最新快照 读优化查询和快照查询相同仅访问基本文件,提供给定文件片自上次执行压缩操作以来的数据。通常查询数据的最新程度的保证取决于压缩策略![](https://www.icode9.com/i/l/?n=22&i=blog/1109757/202202/1109757-20220226214255141-1402556802.png)
表类型解析
1.Copy On Write
简称COW,它实在数据写入的时候,复制一份原来的拷贝,在其基础上添加新数据 正在读数据的请求,读取的是最近的完整副本,这类似于MySQL的MVCC思想![](https://www.icode9.com/i/l/?n=22&i=blog/1109757/202202/1109757-20220226214255178-1282798683.png)
![](https://www.icode9.com/i/l/?n=22&i=blog/1109757/202202/1109757-20220226214255205-687350061.png)
2.Merge On Read
简称MOR,新插入的数据存储在delta log中,定期再将delta log合并进行parquet数据文件 读取数据时,会将delta log跟老的数据文件做merge,得到完整的数据返回![](https://www.icode9.com/i/l/?n=22&i=blog/1109757/202202/1109757-20220226214255184-417544623.png)
![](https://www.icode9.com/i/l/?n=22&i=blog/1109757/202202/1109757-20220226214255309-1113120012.png)
![](https://www.icode9.com/i/l/?n=22&i=blog/1109757/202202/1109757-20220226214255326-1763443950.png)
COW vs MOR
对于写时复制(COW)和读时合并(MOR)writer来说,Hudi的WriteClient是相同的。 COW表:用户在snapshot读取的时候会扫描所有最新的FileSlice的base file MOR表:在READ OPTIMIZED模式下,只会读最近的经过compaction的commit![](https://www.icode9.com/i/l/?n=22&i=blog/1109757/202202/1109757-20220226214255163-10389637.png)
标签:文件,存储,Hudi,批式,流式,查询,增量,类型,数据 来源: https://www.cnblogs.com/EnzoDin/p/15940596.html