数据湖——Hudi基本概念

这篇具有很好参考价值的文章主要介绍了数据湖——Hudi基本概念。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

Hudi

传送门

特性

  • 可插拔索引机制支持快速的Upsert/Delete

  • 支持增量拉取表变更以进行处理

  • 支持事务提交及回滚,并发控制

  • 支持spark、presto、hive、flink等引擎的sql读写

  • 自动管理小文件,数据聚簇、压缩、清理

  • 流式摄入,内置CDC

  • 内置可扩展存储访问的元数据跟踪

  • 向后兼容的方式实现表结构变更的支持

场景

近实时写入、近实时分析、增量的pipline、增量导出

核心概念

基本概念

时间轴
  • 由每一个instants组成,每个instant由三个部分组成:
    • Action
      • COMMITS- 提交表示将一批记录原子写入表中。
      • CLEANS- 后台活动,用于删除表中不再需要的旧版本文件。
      • DELTA_COMMIT- 增量提交是指将一批记录原子写入 MergeOnRead 类型表,其中部分/全部数据可以只写入增量日志。
      • COMPACTION- 协调Hudi中差异数据结构的后台活动,例如:将更新从基于行的日志文件移动到列格式。在内部,压缩表现为时间轴上的特殊提交
      • ROLLBACK- 指示提交/增量提交不成功 & 已回滚,删除在此类写入期间生成的任何部分文件
      • SAVEPOINT- 将某些文件组标记为“已保存”,以便清理程序不会删除它们。它有助于将表还原到时间轴上的某个点,以防发生灾难/数据恢复方案。
    • Time,通常是时间戳,以操作的开始时间顺序单调增加
    • State
      • REQUESTED- 表示已计划操作,但尚未启动
      • INFLIGHT- 表示当前正在执行操作
      • COMPLETED- 表示完成时间轴上的操作
  • 时间概念
    • Arrival time:数据到达Hudi的时间,commit time
    • Event time:record中记录的时间,也就是数据自带的时间

这里之所以不用担心迟到的数据消费不到,是因为此事件有事件自带的时间,自然也会隶属于所在的时间分区

文件布局
  • hudi表

    • 元数据区(.hoodie)
      • instant1、instant2
    • 数据区(分区)
      • 分区1:dayFile、logFile
      • 分区2:dayFile、logFile
  • hudi分区中有文件组的概念,文件组存在唯一标识ID,每个文件组包含多个文件片,一个文件片包含:

    • 一个基本文件(.parquet):在某个commit/compaction即时时间(instant time)生成的(MOR可能没有)
    • 多个日志文件(.log.*),这些日志文件包含自生成基本文件以来对基本文件的插入/更新(COW没有)
  • hudi采用了多版本并发控制,也就是对应了多版本的数据------多文件片

    • compaction操作:合并日志和基本文件以产生新的文件片
    • clean操作:清除不使用的/旧的文件片以回收文件系统上的空间
  • Hudi的base file(parquet 文件)在 footer 的 meta 去记录了 record key 组成的 BloomFilter,用于在 file based index 的实现中实现高效率的 key contains 检测。只有不在 BloomFilter 的 key 才需要扫描整个文件消灭假阳------索引检测key是否存在

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

索引
  • hudi提供了高效的upserts,具体是将hoodie key(record key+partition path)与文件id(文件组)建立唯一映射

    • 数据第一次写入文件后保持不变,一个FileGroup包含了一批record的所有版本记录。index用于区分消息是insert还是update

    • 此做法的意义在于,当更新的数据到了之后可以快速定位到对应的FileGroup,避免了不必要的更新,只需要在FileGroup内做合并

  • 索引的类型

index 原理 优点 缺点
Bloom Index 默认配置,使用布隆过滤器来判断记录存在与否,也可选使用record key的范围裁剪需要的文件 效率高,不依赖外部系统,数据和索引保持一致性 因假阳性问题,还需回溯原文件再查找一遍
Simple Index 把update/delete操作的新数据和老数据进行join 实现最简单,无需额外的资源 性能比较差
HBase Index 把index存放在HBase里面。在插入 File Group定位阶段所有task向HBase发送 Batch Get 请求,获取 Record Key 的 Mapping 信息 对于小批次的keys,查询效率高 需要外部的系统,增加了运维压力
Flink State-based Index HUDI 在 0.8.0 版本中实现的 Flink witer,采用了 Flink 的 state 作为底层的 index 存储,每个 records 在写入之前都会先计算目标 bucket ID。 不同于 BloomFilter Index,避免了每次重复的文件 index 查找
  • 全局索引/非全局索引

    • 全局索引:全局索引在全表的所有分区范围下强制要求键的唯一性,也就是确保对给定的键有且只有一个对应的记录。全局索引提供了更强的保证,但是随着表增大,update/delete 操作损失的性能越高,因此更适用于小表。

    • 非全局索引:默认的索引实现,只能保证数据在分区的唯一性。非全局索引依靠写入器为同一个记录的update/delete提供一致的分区路径,同时大幅提高了效率,更适用于大表。

    • HBase索引本质上是一个全局索引,bloom和simple index都有全局选项:

      hoodie.index.type=GLOBAL_BLOOM
      hoodie.index.type=GLOBAL_SIMPLE
      
  • 索引的选择

    • 大部分的更新会在较新的几个时间分区上,只有小部分会在旧的分区,这种可以使用布隆索引,如果record key是有序的,那就可以通过范围进一步筛选;如果更加高效的使用布隆过滤器进行比对,hudi缓存了输入记录并且使用了自定义的分区器和统计的规律来解决了数据的倾斜,如果假阳性率较高,查询会增加数据的打乱操作,也会根据数据量来调整大小从而达到设定的假阳性率
    • 事件流数据,比如从kafka或者其他消息件发出的数据,插入和更新只存在于最新的几个分区中,重复事件较多,所以在入湖之前去重是一个常见的需求;虽然可以使用hbase索引进行去重,但索引存储的消耗还是会随着事件的增长而线性增长,所以有范围裁剪的布隆索引才是最佳的解决方案,可以使用事件时间戳+事件id组成的键作为去重条件
    • 对维度表的随机更新,使用布隆裁剪就不合适,直接使用普通简单索引就合适,直接将所有的文件的所需字段连接;也可以采用HBase索引,其对这些表能提供更加优越的查询效率;当遇到分区内数据需要更新时,较为适合采用Merge-On-Read表
表类型
  • Copy On Write

    • 只有数据文件/基本文件(.parquet),没有增量日志文件(.log.*)
    • 对于每一个新批次的写入都将创建相应数据文件的版本(新的FileSlice),也就是第一次写入文件为fileslice1,第二次更新追加操作就是fileslice2

    数据湖——Hudi基本概念

    • data_file1 和 data_file2 都将创建更新的版本,data_file1 V2 是data_file1 V1 的内容与data_file1 中传入批次匹配记录的记录合并
    • cow是在写入期间进行合并,因此会产生一些延时,但是它最大的特点在于简单性,不需要其他表的服务,也相对容易调试
  • Merge On Read

    • 可能包含列存的基本文件(.parquet)和行存的增量日志文件(基于行的avro格式,.log文件)

    • 所以对于初始的文件也是追加的avro文件,后续修改追加的文件是avro文件,而且只有在读的时候或者compaction才会合并成列文件

      数据湖——Hudi基本概念

    • compaction可以选择内联或者异步方式,比如可以将压缩的最大增量日志配置为 4。这意味着在进行 4 次增量写入后,将对数据文件进行压缩并创建更新版本的数据文件

    • 不同索引写文件会有差异,布隆索引插入还是写入parquet文件,只有更新才会写入avro文件,因为当parquet文件记录了要更新消息的FileGroupID;而对于Flink索引可以直接写入avro文件

  • COW与MOR的对比

CopyOnWrite MergeOnRead
数据延迟
查询延迟
Update(I/O) 更新成本 高(重写整个Parquet文件) 低(追加到增量日志)
Parquet文件大小 低(更新成本I/O高) 较大(低更新成本)
写放大 低(取决于压缩策略)

所以,cow适合批次处理,mor适合批流一体但更适合流式计算

查询类型
  • 快照查询 Snapshot Queries

    • 全量最新数据:cow直接查最新的parquet文件,mor表需要做一个合并------最新全量数据

      数据湖——Hudi基本概念

  • 增量查询 Incremental Queries

    • 可以查询给定commit/delta commit即时操作以来新写入的数据。有效的提供变更流来启用增量数据管道------最新增量数据
  • 读优化查询 Read Optimized Queries

    • 可查看给定的commit/compact即时操作的表的最新快照。仅将最新文件片的基本/列文件暴露给查询,并保证与非Hudi表相同的列查询性能------并不是全量最新,只是合并时文件

      数据湖——Hudi基本概念

  • 不同表支持的查询类型

    数据湖——Hudi基本概念

数据写

upsert
  • cow
    • 先对数据按照record key去重
    • 创建索引rocord key+分区路径+文件组id;并且通过索引区分哪些数据是更新,哪些数据是新增(key第一次写入)
    • 对于更新的数据,会定位到key所在的最新的文件片的base文件(parquet文件),做合并写到新的文件片内
    • 对于新增的数据
      • 会先扫面当前分区下的小文件,存在就合并写到新的文件片
      • 不存在就写新的FileGroup+FileSlice(文件片)
  • mor
    • 先对数据按照record key去重(可选)
    • 创建索引rocord key+分区路径+文件组id;并且通过索引区分哪些数据是更新,哪些数据是新增(key第一次写入)
    • 对于新增的数据
      • 如果不可建索引,会尝试合并分区内最小的base file(也就是不包含log 文件的FileSlice),生成新的FileSlice,如果没有base File就新写一个FileGroup + FileSlice + base file
      • 如果log file可以建索引,会尝试追加到小的log file内,如果没有log file就新写一个FileGroup + FileSlice + base file
    • 对于更新的数据,写对应的file group+file slice,直接追加到最新的log file(如果当时是最小的小文件,会合并base file,生成新的file slice)
    • log file的大小达到一定的阈值会滚动生成一个新的文件
insert
  • cow

    • 先对 records 按照 record key 去重(可选)
    • 不会创建index
    • 如果有小的base file文件,就合并生成新的fileslice+base file,否则就写新的fileslice+base file
  • mor

    • 先对 records 按照 record key 去重(可选)
    • 不会创建index
    • 如果log file可创建索引,并且有小的fileslice,尝试追加或写到最新log file,如果log file不可索引,就写一个新的fileslice+base file
insert overwrite

在同一分区中创建新的文件组集,现有的文件组被标记为“删除”,根据新记录的数量创建新的文件组

key的生成策略

record key可以用多个字段组合,parition path支持多个字段组合(多层分区)

删除策略
  • 逻辑删除:value字段标记为null
  • 物理删除:
    • 通过 OPERATION_OPT_KEY 删除所有的输入记录
    • 配置 PAYLOAD_CLASS_OPT_KEY =org.apache.hudi.EmptyHoodieRecordPayload 删除所有的输入记录
    • 在输入记录添加字段:_hoodie_is_deleted

数据读

  • 快照读:读取所有 partiiton 下每个 FileGroup 最新的 FileSlice 中的文件,Copy On Write 表读 parquet 文件,Merge On Read 表读 parquet + log 文件

  • 增量读:当前的 Spark data source 可以指定消费的起始和结束 commit 时间,读取 commit 增量的数据集。但是内部的实现不够高效:拉取每个 commit 的全部目标文件再按照系统字段 _ hoodie_commit_time_ apply 过滤条件

  • 流读:0.8.0 版本的 HUDI Flink writer 支持实时的增量订阅,可用于同步 CDC 数据,日常的数据同步 ETL pipeline。Flink 的 streaming 读做到了真正的流式读取,source 定期监控新增的改动文件,将读取任务下派给读 task。

  • Compaction

    • 没有 base file:走 copy on write insert 流程,直接 merge 所有的 log file 并写 base file
    • 有 base file:走 copy on write upsert 流程,先读 log file 建 index,再读 base file,最后读 log file 写新的 base file

Flink 和 Spark streaming 的 writer 都可以 apply 异步的 compaction 策略,按照间隔 commits 数或者时间来触发 compaction 任务,在独立的 pipeline 中执行。文章来源地址https://www.toymoban.com/news/detail-495857.html

到了这里,关于数据湖——Hudi基本概念的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 基于数据湖的多流拼接方案-HUDI概念篇

    目录 一、为什么需要HUDI? 1. 传统技术选型存在哪些问题? 2. Hudi有什么优点? 基于 Hudi Payload 机制的多流拼接方案: 二、HUDI的应用场景 1. 什么场景适合使用hudi? 2. 什么场景不适合使用hudi? 三、什么是HUDI?HUDI能做什么? 1. 什么是HUDI? 2. HUDI能做什么(特性)? 四、HU

    2024年02月11日
    浏览(41)
  • MySQL索引1——索引基本概念与索引结构(B树、R树、Hash等)

    目录 索引(INDEX)基本概念 索引结构分类 B+Tree树索引结构 Hash索引结构 Full-Text索引 R-Tree索引 什么是索引 索引是帮助MySQL高效获取数据的有序数据结构 为数据库表中的某些列创建索引,就是对数据库表中某些列的值通过不同的数据结构进行排序 为列建立索引之后,数据库除了

    2024年02月14日
    浏览(40)
  • 尚硅谷ES基础 - RESTful & JSON&基本概念&倒排索引&HTTP

    RESTful JSON REST 指的是一组架构约束条件和原则。满足这些约束条件和原则的应用程序或设计就是 RESTful。 Web 应用程序最重要的 REST 原则是,客户端和服务器之间的交互在请求之间是无状态的。从客户端到服务器的每个请求都必须包含理解请求所必需的信息。如果服务器在请求

    2024年02月21日
    浏览(34)
  • Hudi(19):Hudi集成Flink之索引和Catalog

    目录 0. 相关文章链接 1. Bucket索引(从 0.11 开始支持) 1.1. WITH参数 1.2. 和 state 索引的对比 2. Hudi Catalog(从 0.12.0 开始支持) 2.1. 概述 2.2. WITH 参数 2.3. 使用dfs方式  Hudi文章汇总          默认的 flink 流式写入使用 state 存储索引信息:primary key 到 fileId 的映射关系。当

    2024年02月05日
    浏览(38)
  • Hudi的7种索引

    Bloom Index (default) 使用根据记录键构建的bloom过滤器,也可以使用记录键范围修剪候选文件.原理为计算RecordKey的hash值然后将其存储到bitmap中,为避免hash冲突一般选择计算3次 HoodieKey 主键信息 :主要包含recordKey 和patitionPath 。recordkey 是由hoodie.datasource.write.recordkey.field 配置项根

    2024年02月14日
    浏览(33)
  • 独家特性 | 腾讯云大数据ES:一站式索引全托管,自治索引大揭秘!

    自治索引是腾讯云ES推出的一站式索引全托管解决方案,应用于日志分析、运维监控等时序数据场景,提供分片自动调优、查询裁剪、故障自动修复、索引生命周期管理等功能。可在降低运维与管理成本的同时,提高使用效率与读写性能。 腾讯云ES团队从大量的运营实践中发

    2023年04月10日
    浏览(56)
  • MySQL数据库索引机制

    MySQL是一款有客户端和服务端的网络应用,mysql是它的客户端,mysqld是它的服务端。服务端本质就是一个进程,它存在于内存当中。而我们存储在MySQL中的数据是保存在磁盘上的,当我们对MySQL中数据进行增删查改操作时,不可能是直接在磁盘上进行操作,而是将对应的数据加

    2024年02月12日
    浏览(72)
  • 大数据 HDFS 的历史、特性、适用场景 运行机制、数据布局、读写流程、容错机制等

    作者:禅与计算机程序设计艺术 大数据的快速增长、高并发、海量数据、多样化的数据源、动态变化的数据特征,给数据的分析、挖掘带来了巨大的挑战。而HDFS就是存储大数据的一个关键组件。HDFS是一个分布式文件系统,主要用来存储和处理超大规模的数据集。HDFS可以方便

    2024年02月08日
    浏览(45)
  • Hudi核心概念

    Instant由3个部分组成: (1)Timestamp,时间戳,什么时候做的操作 (2)Action,操作,具体做了什么操作,COMMIT(提交,COW)、DELTA_COMMIT(提交,MOR)、CLEAN(清理)、COMPACTION(压缩) (3)State,这一个操作具体到哪个步骤了(REQUESTED(请求发起)、INFLIGHT(请求进行中)、

    2024年02月06日
    浏览(37)
  • 数据库索引结构(1)概念

    MySQL学习笔记-主键索引和二级索引_mysql中主键索引和二级索引的区别_爱因诗贤的博客-CSDN博客 MYSQL-主键索引与二级索引_mysql二级索引存在哪个文件_青苔小榭的博客-CSDN博客       采用主键索引的好处:如果元素的位置发生修改,那么查找的复杂度没有变化 因为只是根据主键

    2024年02月06日
    浏览(40)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包