Hudi Indexing(索引)

Hudi通过一种索引机制,将给定的Hoodie key(record key + partition path)一致地映射到file ID,从而提供了高效的upserts操作。一旦记录的第一个版本被写入文件中,record key和file group/file ID之间的映射关系就不会再改变。简而言之,映射的file group包含了一组记录的所有版本。

对于Copy-On-Write表,这种设计可以通过避免对整个数据集进行join操作来实现快速的upsert和delete操作。对于Merge-On-Read表,这种设计允许Hudi限制任何给定base files需要与之合并的记录数量。具体而言,给定的base file只需要与属于该base file的记录的更新进行合并。相比之下,没有索引组件的设计(例如:Apache Hive ACID)可能需要将所有base file与所有的更新/删除记录进行合并。

image.png

Hudi Index Type

Hudi支持以下几种索引类型:

  • Bloom Filter index(default):Bloom Filter是一种快速的数据结构,用于判断某个元素是否存在于集合中。Hudi使用使用由record key构建的布隆过滤器,还可以选择使用record key range修剪候选文件。
  • Simple Index:Simple index是基于record key构建的索引,用于快速定位特定记录。它将record key与对应的file ID进行映射,从而可以快速定位到包含特定记录的文件。具体到code层面,Hudi对incoming的update/delete记录,与存储中提取的record key -> file location的映射,进行join操作,从而找到该记录应该位于的文件。
  • HBase Index:在外部的Hbase table中存储映射关系。
  • 自定义实现:可以通过实现HoodieIndex interface,定义自己的索引方式。

相关配置:

1.hoodie.index.type
Type of index to use. Default is SIMPLE on Spark engine, and INMEMORY on Flink and Java engines. Possible options are [BLOOM | GLOBAL_BLOOM |SIMPLE | GLOBAL_SIMPLE | INMEMORY | HBASE | BUCKET]. Bloom filters removes the dependency on a external system and is stored in the footer of the Parquet Data Files

2.hoodie.index.class
Full path of user-defined index class and must be a subclass of HoodieIndex class. It will take precedence over the hoodie.index.type configuration if specified

另一个值得了解的关键点是全局索引和非全局索引之间的区别。Bloom和simple索引都有全局选项hoodie.index.type=GLOBAL_BLOOM 和 hoodie.index.type=GLOBAL_SIMPLE。HBase索引本质上是一个全局索引。

  • Global Index:全局索引在表的所有分区中强制确保键的唯一性,即确保表中存在一个且仅有一个与给定记录键相对应的记录。全局索引提供了更强的保证,但是更新/删除的成本随着表的大小增长(O(表的大小)),这对于较小的表可能仍然可以接受。
  • Non-Global Index:非全局索引的实现仅在特定分区内强制执行此约束。可以想象,非全局索引依赖于写入者在更新/删除期间为给定的记录键提供相同一致的分区路径,但由于索引查找操作变为O(更新/删除的记录数),因此可以提供更好的性能,并且与写入量的增加成比例。

由于数据以不同的数据量、速度和具有不同的访问模式进入,不同的索引可以用于不同的工作负载类型。让我们逐步了解一些典型的工作负载类型,并看看如何为这些用例充分利用正确的Hudi索引。这基于我们的经验,您应该认真决定是否相同的策略最适合您的工作负载。

索引选择策略

场景一:事实表的延迟到达更新

许多公司将大量的事务数据存储在NoSQL数据存储中。例如,在拼车服务中的行程表,股票的买卖,电子商务网站中的订单等。这些表通常是不断增长的,最新数据上有随机更新,而长尾更新则涉及较旧的数据,这可能是由于交易在较晚的日期结算或数据更正所致。换句话说,大多数更新进入最新的分区,而较旧的分区只有少量更新。


image.png

对于这种工作负载,BLOOM索引表现良好,因为索引查找将根据合适大小的布隆过滤器剪枝掉很多数据文件。此外,如果可以构建键以具有一定的排序,那么通过范围剪枝,需要比较的文件数量进一步减少。Hudi使用所有文件键范围构建了一个区间树,并有效地过滤掉在更新/删除的记录中不匹配任何键范围的文件。
为了以最小的布隆过滤器读取次数和在执行器之间均匀分布工作的方式,有效地将传入的记录键与布隆过滤器进行比较,Hudi利用输入记录的缓存,并使用自定义分区器来消除数据倾斜。有时,如果布隆过滤器的误报率很高,可能会增加执行查找所需的shuffle数据量。Hudi支持动态布隆过滤器(使用hoodie.bloom.index.filter.type=DYNAMIC_V0启用),它根据给定文件中存储的记录数量来调整其大小,以提供配置的误报率。

场景二:事件表中的去重

事件流正在无处不在。来自Apache Kafka或类似消息总线的事件通常是事实表的10-100倍大小,并且通常将"时间"(事件到达时间/处理时间)视为重要因素。例如,物联网事件流、点击流数据、广告展示等。插入和更新仅跨越最后几个分区,因为这些数据大多是追加方式。由于重复事件可能在端到端的流程中的任何位置引入,所以在存储到数据湖之前进行去重是常见需求。


image.png

一般来说,这是一个非常具有挑战性且需要低成本解决的问题。尽管我们可以使用键值存储来执行此去重操作,并结合HBASE索引,但索引存储成本将随事件数量线性增长,因此可能变得过于昂贵。事实上,带有范围剪枝的BLOOM索引是在这种情况下的最佳解决方案。可以利用时间通常是一个重要因素的事实,并构建一个键,例如event_ts + event_id,以便插入的记录具有单调递增的键。这样可以通过在最新的表分区中剪枝大量的文件,从而获得很大的性能提升。

场景三:对于维度表的随机更新/删除

这些类型的表通常包含高维数据,并包含参考数据,例如用户配置文件、商家信息等。这些是高保真度的表,更新通常很小,但分布在许多分区和数据文件中,涵盖了从旧到新的整个数据集。通常,这些表也是未分区的,因为没有一个很好的方法来对这些表进行分区。


image.png

如前所讨论,如果无法通过比较范围/过滤器剪枝掉很多文件,那么BLOOM索引可能不会带来好处。在这种随机写入的工作负载中,更新操作会涉及到表中的大多数文件,因此根据某些传入的更新,布隆过滤器通常会对所有文件表示为真阳性。因此,我们最终需要比较范围/过滤器,并将传入的更新与所有文件进行对比。在这种情况下,SIMPLE索引会更适合,因为它不会基于先前的剪枝操作,而是直接与每个数据文件中的record key字段进行连接。如果操作开销可接受,HBASE索引也可以使用,它可以为这些表提供更好的查找时间。

注意

在使用全局索引时,用户还应考虑设置hoodie.bloom.index.update.partition.path=true或hoodie.simple.index.update.partition.path=true,以处理分区路径值可能由于更新而发生变化的情况,例如按家庭城市分区的用户表;用户搬到了另一个城市。这些表也是适合使用Merge-On-Read表类型的优秀候选表。

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

推荐阅读更多精彩内容