请注意本文中涵盖的索引是为写入端准备的,这与读取端索引不同。
写入端索引抽象在 HoodieIndex 定义。我将在下面介绍一些关键的 API,以便大致了解索引的含义。
tagLocation()
:当一组输入记录在写入过程中传递到索引组件时,将调用此 API 来标记每条记录,确定它是否存在于表中,然后将其与其位置信息相关联。生成的记录集称为"标记记录"。在 HoodieRecord 模型中,“currentLocation”字段将由此标记过程填充。updateLocation()
:写入存储后,某些索引需要更新位置信息才能与数据表同步。对于这些适用的索引类型,此过程仅在 IO 后阶段执行。isGlobal()
:Hudi 将索引分为全局类型和非全局类型。全局索引标识所有表分区中的唯一记录,因此相对于表是"全局"的。另一方面,非全局索引在分区级别验证唯一性。通常非全局索引由于扫描空间较小,因此性能更好。但是,它们不适用于具有可以在分区之间切换的记录的表。canIndexLogFiles()
:由于实现的特殊性,某些索引能够在读取时合并表的日志文件上建立索引。此特性会影响编写器创建文件写入句柄的方式:如果配置的索引为真,则插入将通过 AppendHandle 路由到日志文件。isImplicitWithStorage()
:这是一个特征,指示索引是否与存储上的数据文件一起隐式"持久化"。某些索引单独存储其索引数据。Hudi 提供了几种开箱即用的索引类型,以适应不同的流量模式和表大小。为每个表选择最合适的索引是一个关键的调整步骤。这篇文章很好地解释了做出正确选择的重要性。在以下各节中,我将说明写入端索引的内部工作原理以增强理解。
简单索引是非全局索引,目前用作默认类型。它背后的主要概念涉及扫描相关分区中的所有基本文件,以确定传入的记录是否与任何提取的键匹配。
在左联接操作中,如果输入记录与提取的键匹配,则联接结果将包含位置信息,然后该信息将用于填充 HoodieRecord 的 "currentLocation" 字段。这会产生所谓的“标记记录”。这些不匹配的记录将保持原样,并与标记的记录合并以供进一步处理。
简单索引有一个称为全局简单索引的全局版本,与非全局对应项不同,它将输入与来自所有分区的基本文件进行匹配,而不仅仅是相关分区。更新记录的分区值时,将加载相应的文件组,其中还包括 MoR 表的日志文件,以执行额外的标记步骤:它将传入记录与其现有的旧版本合并,并将合并的结果标记到新分区中的位置。由于简单索引倾向于在分区级别或表级别加载所有基本文件,因此它们非常适合具有随机或均匀分布的数据访问的流量模式。
Bloom Index 遵循与 Simple Index 类似的高级流程。然而 Bloom Index 背后的独特概念在于它最大限度地减少了用于查找的键和文件的数量,同时保持了较低的读取成本。
Bloom Index 采用 2 阶段过滤来减少用于查找的键和文件的数量。
请注意,查找之前的过滤过程仅涉及读取文件页脚,因此读取成本较低。
就像简单索引一样,Bloom索引也有一个全局版本,称为全局Bloom索引。它的操作与非全局版本类似,尽管是在表级别,并且采用与全局简单索引相同的逻辑来处理分区更新方案。
存储桶索引是基于哈希设计的,允许我们使用固定的哈希函数一致地将键映射到文件组,从而消除了任何磁盘读取的需要,从而节省了大量时间。存储桶索引有两种变体 - 简单存储桶索引和一致存储桶索引。Simple Bucket Index 分配固定数量的存储桶,每个存储桶映射到一个文件组,这反过来又限制了表中文件组的总数。这会导致处理数据偏斜和横向扩展的缺点。另一方面,一致存储桶索引旨在克服这些缺点,当相应的文件组超过特定大小阈值时,将现有存储桶动态重新散列为子存储桶。
HBase 索引是使用外部运行的 HBase 服务器实现的。它存储记录键与相关文件组信息之间的映射,并且是一个全局索引。在大多数情况下,这为标记提供了有效的查找,并且可以随着表大小的增加而轻松横向扩展。但是缺点是管理其他服务器所涉及的操作开销。
记录索引是 0.14.0 版中新添加的功能,其操作逻辑类似于 HBase 索引:它也是一个全局索引,用于保存记录键和文件组的映射。关键的改进在于将索引数据保留在 Hudi 表的本地,从而避免了运行额外服务器的成本。有关详细讨论,请参阅此博客[1]。
在这篇文章中,我们讨论了面向写入端的 Hudi 索引 API,深入研究了 简单索引 和 Bloom 索引 的详细流程,并简要介绍了 Bucket Index、HBase Index 和 Record Index。
[1]
此博客: [https://hudi.apache.org/blog/2023/11/01/record-level-index](https://hudi.apache.org/blog/2023/11/01/record-level-index)