Hudi系列3:Hudi核心概念

Hudi架构

image.png

一. 时间轴(TimeLine)

1.1 时间轴(TimeLine)概念

Hudi的核心是维护在不同时刻(Instant)在表上执行的所有操作的时间轴,提供表的即时视图,同时还有效地支持按时间顺序检索数据


image.png

1.2 Hudi的时间线由组成

Instant action:
在表上执行的操作类型

Instant time:
即时时间,通常是一个时间戳,它按照action的开始时间单调递增

State:
时刻的当前状态

1.3 时间线上的Instant action操作类型

hudi保证在时间线上的操作都是基于即时时间的,两者的时间保持一致并且是原子性的

  1. commits: 表示将一批数据原子写入表中

  2. cleans: 清除表中不在需要的旧版本文件的后台活动。

  3. delta_commit:增量提交是指将一批数据原子性写入MergeOnRead类型的表中,其中部分或者所有数据可以写入增量日志中。

  4. compaction: 协调hudi中差异数据结构的后台活动,例如:将更新从基于行的日志文件变成列格式。在内部,压缩的表现为时间轴上的特殊提交。

  5. rollback:表示提交操作不成功且已经回滚,会删除在写入过程中产生的数据

  6. savepoint:将某些文件标记为“已保存”,以便清理程序时不会被清楚。在需要数据恢复的情况下,有助于将数据集还原到时间轴上某个点。

1.4 时间线上State状态类型

任何给定的瞬间都可以处于以下状态之一

  1. requested:表示一个动作已被安排,但尚未启动

  2. inflight:表是当前正在执行操作

  3. completed:表是在时间线上完成了操作

1.5 时间线官网实例

image.png

上图中采用时间(小时)作为分区字段,从 10:00 开始陆续产生各种 commits,10:20 来了一条 9:00 的数据,该数据仍然可以落到 9:00 对应的分区,通过 timeline 直接消费 10:00 之后的增量更新(只消费有新 commits的 group),那么这条延迟的数据仍然可以被消费到,(没有说明白它是怎么处理延迟数据的)

二. 文件布局

Hudi将一个表映射为如下文件结构:


image.png
  1. Hudi将HDFS上的数据集组织到基本路径(HoodieWriteConfig.BASEPATHPROP)下的目录结构中。

  2. 数据集分为多个分区(DataSourceOptions.PARTITIONPATHFIELDOPT_KEY),这些分区与Hive表非常相似,是包含该分区的数据文件的文件夹。

  3. 数据集分为多个分区(DataSourceOptions.PARTITIONPATHFIELDOPT_KEY),这些分区与Hive表非常相似,是包含该分区的数据文件的文件夹。

image.png
  1. Hudi将数据表组织成分布式文件基本路径(basepath)下的目录结构。

  2. 表被划分为多个分区,这些分区是包含该分区的数据文件的文件夹,非常类似于Hive表

  3. 在每个分区中,文件被组织成文件组,由文件ID唯一标识

  4. 每个文件组包含几个文件片(FileSlice)

  5. 每个文件包含:
    5.1) 一个基本文件(.parquet): 在某个commit/compaction 即时时间(instant time)生成的(MOR可能没有)
    5.2) 多个日志文件(.log*),这些日志文件包含自生成基本文件以来对基本文件的插入/更新(COW没有).

  6. Hudi采用了多版本并发控制(Multiversion Concurrency Control,MVCC)
    6.1) compaction 操作: 合并日志和基本文件以产生新的文件片
    6.2) clean操作: 清楚不使用的/旧的文件以回收文件系统上的空间

  7. Hudi的base file(parquet 文件)在 footer 的 meta 去记录了 record key组成的BloomFilter,用于在flie based index 的实现中实现高效率的 key contains 检测。 只有不在 BloomFilter的key才需要扫描整个文件消灭假阳。

  8. Hudi的log(avro 文件)是自己编码的,通过积攒数据 buffer 以LogBlock为单位写出,每个LogBlock包含 magic number、size、content、footer等信息,用于数据读、校验和过滤。

三. 索引

3.1 简介

Hudi 通过索引机制将给定的 hoodie 键(记录键 + 分区路径)一致地映射到文件 id,从而提供高效的 upsert。记录键和文件组/文件 id 之间的这种映射,一旦记录的第一个版本被写入文件,就永远不会改变。简而言之,映射文件组包含一组记录的所有版本(类似git)。

3.2 对比Hive没有索引的区别

对于Copy-On-Write 表,这可以实现快速 upsert/delete 操作,避免需要连接整个数据集以确定要重写哪些文件。对于Merge-On-Read 表,这种设计允许 Hudi 绑定任何给定基本文件需要合并的记录数量。具体来说,给定的基本文件只需要针对作为该基本文件一部分的记录的更新进行合并。相反,没有索引组件的设计 Hive ACID需要将所有基本文件与所有传入的更新/删除记录合并


image.png

3.3 Hudi索引类型

image.png

3.4 全局索引与非全局索引

Bloom 和 simple index 都有全局选项,Base 索引本质上是一个全局索引

hoodie.index.type=GLOBAL_BLOOM
hoodie.index.type=GLOBAL_SIMPLE
  1. 全局索引:在全表的所有分区范围下强制要求键保持唯一,即确保对给定的键有且只有一个对应的记录。

  2. 非全局索引:仅在表的某一个分区内强制要求键保持唯一,它依靠写入器为同一个记录的更删提供一致的分区路。

四. 表类型

4.1 COW:(Copy on Write)写时复制表

4.1.1 概念

Copy on Write表中的文件切片仅包含基本列文件,并且每次提交都会生成新版本的基本文件。换句话说,每次提交操作都会被压缩,以便存储列式数据,因此Write Amplification写入放大非常高(即只有一个字节的数据被提交修改,我们也需要先copy改值所在的最小单位块复制到内存整体修改再写会去),而读取数据成本则没有增加,所以这种表适合于做分析工作,读取密集型的操作。

4.1.2 COW工作原理

image.png

当数据被写入,对现有文件组的更新会为该文件组生成一个带有提交即时间标记的新切片,而插入分配一个新文件组并写入该文件组第一个切片。这些切片和提交即时时间在上图用同一颜色标识。针对图上右侧sql查询,首先检查时间轴上的最新提交并过滤掉之前的旧数据(根据时间查询最新数据),如上图所示粉色数据在10:10被提交,第一次查询是在10:10之前,所以不会出现粉色数据,第二次查询时间在10:10之后,可以查询到粉色数据(以被提交的数据)。

4.1.3 COW表对表的管理方式改进点

  1. 在原有文件上进行自动更新数据,而不是重新刷新整个表/分区

  2. 能够只读取修改部分的数据,而不是浪费查询无效数据

  3. 严格控制文件大小来保证查询性能(小文件会显著降低查询性能)

4.2 MOR:(Merge on Read)读时复制表

4.2.1 概念

Merge on Read表使用列式存储(parquet)+行式文件(arvo)存储数据,它仍然支持只查询文件切片中的基本列(parquet)来对表进行查询优化。用户每次对表文件的upsert操作都会以增量写入delta log(avro),增量日志会对应每个文件最新的ID来帮助用户完成快照查询。因此这种表类型,能够智能平衡读取和写放大(wa),提供近乎实时的数据。这种表最重要的是合并压缩,它用来选择将对应delta log数据合并压缩到表的基本文件中,来保持查询时的性能(较大的增量日志文件会影响合并时间和查询时间)(通俗说就是你修改新增的值存在一个avro格式文件中,等你要查询的时候就好去和原有的值进行合并操作返回唯一值,不过MOR表会定期自动合并)

Merge on Read 读时合并
第一批数据,没有Parquet文件,写入到log文件
后期会compaction,执行合并的时候,将Parquet+log合并为新的
Parquet。(有点类似关系型数据库的WAL)

4.2.2 MOR表工作原理

image.png
  1. 如上图所示,可以做到每一分钟提交一次写入操作

  2. 查询表的方式有两种,Read Optimized query和Snapshot query,取决于我们选择是要查询性能还是数据最新

  3. 如上图所示,Read Optimized query查询不到10:05之后的数据(查询不到增量日志里的数据,没有合并到base文件),而Snapshot query则可以查询到全量数据(基本列数据+行式的增量日志数据)

4.3 总结了两种表类型之间的权衡

image.png

五. 查询类型

Hudi支持如下三种查询类型:

5.1 Snapshot Queries

image.png

5.2 Incremental Queries

增量查询,可以查询给定 commit/delta commit 即时操作以来新写入的数据。 有效的提供变更流来启用增量数据管道。

5.3 Read Optimized Query

读优化查询,可查看给定的 commit、compact 即时操作的表的最新的快照。 仅将最新文件片的基本/列文件暴露给查询,并保证与非Hudi表相同的列查询性能。

参考:

  1. https://hudi.apache.org/docs/overview/
  2. https://www.bilibili.com/video/BV1ue4y1i7na/
  3. https://blog.csdn.net/NC_NE/article/details/125019619
  4. https://yangshibiao.blog.csdn.net/article/details/123123624
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,242评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,769评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,484评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,133评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,007评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,080评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,496评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,190评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,464评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,549评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,330评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,205评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,567评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,889评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,160评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,475评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,650评论 2 335

推荐阅读更多精彩内容