Hudi-核心概念(时间轴、文件管理、索引)


总述

hudi提供了hudi表的概念,这些表支持CRUD操作,可以利用现有的大数据集群比如HDFS做数据文件存储,然后使用SparkSQL或Hive等分析引擎进行数据分析查询   hudi表的三个主要组件 a.有序的时间轴元数据,类似于数据库事务日志 b.分层布局的数据文件:实际写入表中的数据 c.索引(多种实现方式):映射包含指定记录的数据集;数据有唯一主键,可快速定位数据  

1.时间轴Timeline[核心]

在所有的表中维护了一个包含在不同的即时(Instant)时间对数据集操作(比如新增、修改或删除)的时间轴(Timeline) 在每一次对hudi表的数据集操作时都会在该表的Timeline上生成一个Instant,从而可以实现在仅查询某个时间点之后成功提交的数据,或是仅查询某个时间点之前的数据,有效避免了扫描更大时间范围的数据。 同时,可以高效的只查询更改前的文件(如在某个Instant提交了更改操作后,仅query某个时间点之前的数据,则仍可以query修改前的数据) Action:     COMMITS:数据提交     CLEANS:数据删除     DELTA_COMMIT:     COMPACTION:小文件合并     ROLLBACK:回滚     SAVEPOINT:保存点   Timeline是hudi用来管理提交(commit)的抽象,每个commit都绑定一个固定时间戳,分散到时间线上。 在Timeline上,每个commit被抽象为一个HoodieInstant,一个instant记录了一次提交(commit)的行为、时间戳和状态 上图中采用时间(小时)作为分区字段,从10:00开始陆续产生各种commit,10:20来了一条9:00的数据,该数据仍然可以落到9:00对应的分区,通过timeline直接消费10:00之后的增量更新(只消费有新commits的group),那么这条延迟的数据仍然可以被消费到   时间轴的实现类(位于hudi-common-xx.jar中),时间轴相关的实现类位于org.apache.hudi.common.table.timeline包下  

2.文件管理

hudi将DFS上的数据集组织到基本路径(HodieWriteConfig.BASEPATHPROP)下的目录结构中 数据集分为多个分区(DataSourceOptions.PARTITIONPATHFIELDOPT_KEY),这些分区与hive表非常相似,是包含该分区的数据文件的文件夹 在每个分区内,文件被组织为文件组,由文件ID充当唯一标识。每个文件组包含多个文件切片,其中每个切片包含在某个即时时间的提交/压缩生成的基本列文件(.parquet)以及一组日志文件(.log),该文件包含自生成基本文件依赖对基本文件的插入/更新。 数据构成关系:table -> partition -> FileGroup -> FileSlice -> parquet + log   hudi的base file(parquet文件)在footer的meta去记录了record key组成的BloomFilter,用于在file based index的实现中实现高效率的key contains检测 hudi的log(arvo文件)是自己编码的,通过积攒数据buffer以LogBlock为单位写出,每个LogBlock包含magic number、size、content、footer等信息,用于数据读、校验和过滤  

3.索引index

hudi通过索引机制提供高效的Upsert操作,该机制会将一个RecodeKey + PartitionPath组合的方式作为唯一标识映射到一个文件ID,而且这个唯一标识和文件组/文件ID之间的映射自记录被写入文件组开始就不会再改变。 3.1全局索引:在全表的所有分区范围下强制要求键保持唯一,即确保对给定的键有且只有一个对应的记录。 3.2非全局索引:仅在表的某一个分区内强制要求键保持唯一,它依靠写入器为同一个记录的更新、删除提供一致的分区路径