总览
Apache Hudi根据不同的表类型、配置参数来帮助您构建和管理数据湖,以满足每个人的需要。Hudi添加了每个记录的元数据字段,如_hoodie_record_key
, _hoodie_partition path
, _hoodie_commit_time
,它有多种用途。它们有助于避免在合并、压缩和其他表操作期间重新计算记录键、分区路径,还有助于支持记录级增量查询(与仅跟踪文件的其他表格式相比)。此外,即使给定表的键字段在其生命周期内发生了更改,它也通过确保执行唯一的键约束来确保数据质量。但是对于不需要这些好处或关键更改非常少的简单用例,来自社区的反复要求之一是利用现有的字段,而不是添加额外的元字段。
虚拟键支持
Hudi现在支持虚拟键,其中Hudi元字段可以根据需要从数据字段计算。目前,元字段只计算一次,并作为记录元数据存储,并在各种操作中重用。如果不需要增量查询支持,他们可以开始利用Hudi的Virtual key支持,并继续使用Hudi来构建和管理他们的数据湖,以减少每个记录元数据带来的存储开销。
相关配置
可以使用下面的配置为给定的表启用虚拟键。当设置hoodie.population.meta.fields=false
时,Hudi将为相应的表使用虚拟键。此配置的默认值为true,这意味着所有元字段将在默认情况下添加。
一旦启用了虚拟键,就不能对给定的hudi表禁用它,因为已经存储的记录可能没有填充元字段。但如果你有一个旧版本的hudi的现有表,虚拟键可以启用。w.r.t虚拟键支持的另一个约束是,给定表的键生成器属性不能在给定hudi表的生命周期中更改。在这个模型中,用户还分担确保表中键的唯一性的责任。例如,如果您将记录键配置为指向field_5的几批写操作,然后切换到field_10,那么Hudi就不能保证键的唯一性,因为较早的写操作可能对field_10有重复。
使用虚拟键时,每次需要(合并、压缩、MOR快照读取)时都必须重新计算键。因此,我们为Copy-On-Write表上的所有内置键生成器支持虚拟键。支持Merge-On-Read表上的所有键生成器将需要从基日志和增量日志中读取所有字段,从而牺牲核心柱查询性能,这对用户来说是非常昂贵的。因此,我们目前只支持简单的键生成器(默认键生成器,其中记录键和分区路径都引用现有字段)。
CopyOnWrite(COW)表支持的键生成器
SimpleKeyGenerator, ComplexKeyGenerator, CustomKeyGenerator, TimestampBasedKeyGenerator and NonPartitionedKeyGenerator.
MergeOnRead(MOR)表支持的键生成器
SimpleKeyGenerator
支持的索引类型
初始版本只支持SIMPLE以及GOLBAL_SIMPLE,后续计划支持其他像BLOOM等索引。
支持的操作
除了增量查询外,所有现有的特性都支持带有虚拟键的hudi表。这意味着,清理、归档、元数据表、clustering等可以为一个启用虚拟键的hudi表启用。因此,如果您希望这样做,您可以仅仅使用Hudi作为事务性表格式,并与所有出色的表服务运行时和平台服务一起使用,而不会产生与支持增量数据处理相关的任何开销。
样例展示
如之前所述,需要设置hoodie.population.meta.fields=false
来开启虚拟键,接下来看一下开启和未开启虚拟键的区别。
以下是常规hudi表的一些记录示例(禁用虚拟键)
+--------------------+--------------------------------------+--------------------------------------+---------+---------+-------------------+
|_hoodie_commit_time | _hoodie_record_key | _hoodie_partition_path | rider | driver | fare |
+--------------------+--------------------------------------+--------------------------------------+---------+---------+-------------------+
| 20210825154123 | eb7819f1-6f04-429d-8371-df77620b9527 | americas/united_states/san_francisco |rider-284|driver-284|98.3428192817987 |
| 20210825154123 | 37ea44f1-fda7-4ec4-84de-f43f5b5a4d84 | americas/united_states/san_francisco |rider-213|driver-213|19.179139106643607|
| 20210825154123 | aa601d6b-7cc5-4b82-9687-675d0081616e | americas/united_states/san_francisco |rider-213|driver-213|93.56018115236618 |
| 20210825154123 | 494bc080-881c-48be-8f8a-8f1739781816 | americas/united_states/san_francisco |rider-284|driver-284|90.9053809533154 |
| 20210825154123 | 09573277-e1c1-4cdd-9b45-57176f184d4d | americas/united_states/san_francisco |rider-284|driver-284|49.527694252432056|
| 20210825154123 | c9b055ed-cd28-4397-9704-93da8b2e601f | americas/brazil/sao_paulo |rider-213|driver-213|43.4923811219014 |
| 20210825154123 | e707355a-b8c0-432d-a80f-723b93dc13a8 | americas/brazil/sao_paulo |rider-284|driver-284|63.72504913279929 |
| 20210825154123 | d3c39c9e-d128-497a-bf3e-368882f45c28 | americas/brazil/sao_paulo |rider-284|driver-284|91.99515909032544 |
| 20210825154123 | 159441b0-545b-460a-b671-7cc2d509f47b | asia/india/chennai |rider-284|driver-284|9.384124531808036 |
| 20210825154123 | 16031faf-ad8d-4968-90ff-16cead211d3c | asia/india/chennai |rider-284|driver-284|90.25710109008239 |
+--------------------+--------------------------------------+--------------------------------------+---------+----------+------------------+
下面是一些启用了虚拟键的hudi表的示例记录。
+--------------------+------------------------+-------------------------+---------+---------+-------------------+
|_hoodie_commit_time | _hoodie_record_key | _hoodie_partition_path | rider | driver | fare |
+--------------------+------------------------+-------------------------+---------+---------+-------------------+
| null | null | null |rider-284|driver-284|98.3428192817987 |
| null | null | null |rider-213|driver-213|19.179139106643607|
| null | null | null |rider-213|driver-213|93.56018115236618 |
| null | null | null |rider-284|driver-284|90.9053809533154 |
| null | null | null |rider-284|driver-284|49.527694252432056|
| null | null | null |rider-213|driver-213|43.4923811219014 |
| null | null | null |rider-284|driver-284|63.72504913279929 |
| null | null | null |rider-284|driver-284|91.99515909032544 |
| null | null | null |rider-284|driver-284|9.384124531808036 |
| null | null | null |rider-284|driver-284|90.25710109008239 |
+--------------------+------------------------+-------------------------+---------+----------+------------------+
如您所见,存储中的所有元字段都是空的,但所有用户字段保持不变,类似于普通表。
增量查询
由于在虚拟键启用后hudi不维护任何表的元数据(如在记录级别提交时间),所以是不支持增量查询的。如果你做了增量查询,则会出现如下异常:
scala> val tripsIncrementalDF = spark.read.format("hudi").
| option(QUERY_TYPE_OPT_KEY, QUERY_TYPE_INCREMENTAL_OPT_VAL).
| option(BEGIN_INSTANTTIME_OPT_KEY, "20210827180901").load(basePath)
org.apache.hudi.exception.HoodieException: Incremental queries are not supported when meta fields are disabled
at org.apache.hudi.IncrementalRelation.<init>(IncrementalRelation.scala:69)
at org.apache.hudi.DefaultSource.createRelation(DefaultSource.scala:120)
at org.apache.hudi.DefaultSource.createRelation(DefaultSource.scala:67)
at org.apache.spark.sql.execution.datasources.DataSource.resolveRelation(DataSource.scala:344)
at org.apache.spark.sql.DataFrameReader.loadV1Source(DataFrameReader.scala:297)
at org.apache.spark.sql.DataFrameReader.$anonfun$load$2(DataFrameReader.scala:286)
at scala.Option.getOrElse(Option.scala:189)
at org.apache.spark.sql.DataFrameReader.load(DataFrameReader.scala:286)
at org.apache.spark.sql.DataFrameReader.load(DataFrameReader.scala:232)
... 61 elided
总结
希望这个博客对你学习Apache Hudi的另一个特性有用。如果你对Hudi感兴趣并想要投稿,请点击这里。
本文为从大数据到人工智能博主「xiaozhch5」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://lrting.top/backend/2026/