记录级别索引:Apache Hudi 针对大型数据集的超快索引

简介: 记录级别索引:Apache Hudi 针对大型数据集的超快索引

介绍

索引是一个关键组件,有助于 Hudi 写入端快速更新和删除,并且它在提高查询执行方面也发挥着关键作用。Hudi提供了多种索引类型,包括全局变化的Bloom索引和Simple索引、利用HBase服务的HBase索引、基于哈希的Bucket索引以及通过元数据表实现的多模态索引。索引的选择取决于表大小、分区数据分布或流量模式等因素,其中特定索引可能更适合更简单的操作或更好的性能。用户在为不同表选择索引类型时经常面临权衡,因为还没有一种能够以最小的操作开销促进写入和读取的通用性能索引。

从 Hudi 0.14.0 开始,我们很高兴地宣布 Apache Hudi 的通用索引 - 记录级别索引 (RLI)。这一创新不仅显着提高了写入效率,还提高了相关查询的读取效率。RLI 无缝集成在表存储层中,无需任何额外的操作工作即可轻松工作。

在本博客的后续部分中,我们将简要介绍 Hudi 的元数据表,这是讨论 RLI 的先决条件。接下来我们将深入研究 RLI 的设计和工作流程,然后展示性能分析和索引类型比较。该博客将以对 RLI 未来工作作为结尾。

元数据表

Hudi 元数据表[1].hoodie/metadata/ 目录中的读取合并 (MoR) 表。它包含与记录相关的各种元数据,无缝集成到写入器和读取器路径中,以提高索引效率。元数据分为四个分区:文件、列统计信息、布隆过滤器和记录级索引。

元数据表与时间轴上的每个提交操作同步更新,换句话说,对元数据表的提交是对Hudi数据表的事务的一部分。通过包含不同类型元数据的四个分区,此布局可实现多模式索引的目的:

• files分区跟踪Hudi数据表的分区,以及每个分区的数据文件

• column stats分区记录了数据表每一列的统计信息

• bloom filter分区存储基本文件的序列化布隆过滤器

• record level index分区包含各个记录键和相应文件组ID的映射

用户可以通过设置 hoodie.metadata.enable=true 来启用元数据表。一旦启用,文件分区将始终启用。可以单独启用和配置其他分区以利用额外的索引功能。

记录级别索引

从版本 0.14.0 开始,可以通过设置 hoodie.metadata.record.index.enable=truehoodie.index.type=RECORD_INDEX 来激活记录级别索引 (RLI)。RLI 背后的核心概念是能够确定记录的位置,从而减少需要扫描以提取所需数据的文件数量。这个过程通常被称为“索引查找”。Hudi 采用主键模型,要求每个记录与一个键关联以满足唯一性约束。因此我们可以在记录键和文件组之间建立一对一的映射,这正是我们打算在记录级索引分区中存储的数据。

对于索引而言,性能至关重要。包含RLI分区的元数据表选择HFile作为文件格式,HBase的文件格式利用B+树结构进行快速查找。现实工作负载的基准测试表明,包含 100 万个 RLI 映射的 HFile[2] 可以在 600 毫秒内查找一批 100k 记录。我们将在后面的部分中介绍性能主题并进行详细分析。

初始化

为现有 Hudi 表初始化 RLI 分区可能是一项费力且耗时的任务,具体取决于记录的数量。就像典型的数据库一样,构建索引需要时间,但最终会通过加速未来的大量查询而得到回报。

上图显示了 RLI 初始化的步骤。由于这些作业都是可并行的,因此用户可以相应地扩展集群并配置相关的并行设置(例如 hoodie.metadata.max.init.parallelism)以满足他们的时间要求。

重点关注最后一步“批量插入到 RLI 分区”,元数据表写入端使用哈希函数对 RLI 记录进行分区,确保生成的文件组的数量与分区的数量一致。这保证了记录键查找的一致性。

值得注意的是,当前的实现在初始化后修复了 RLI 分区中文件组的数量。因此用户应该倾向于过度配置文件组并相应地调整这些配置。

hoodie.metadata.record.index.max.filegroup.count
hoodie.metadata.record.index.min.filegroup.count
hoodie.metadata.record.index.max.filegroup.size
hoodie.metadata.record.index.growth.factor

在未来的开发迭代中,RLI 应该能够通过动态重新平衡文件组来克服这一限制,以适应不断增加的记录数量。

在数据表写入时更新 RLI

在常规写入期间,RLI 分区将作为事务的一部分进行更新。元数据记录将使用传入的记录键及其相应的位置信息生成。鉴于 RLI 分区包含记录键和位置的精确映射,对数据表的更新插入将导致将相应的键更新插入到 RLI 分区。所采用的哈希函数将保证相同的键被路由到同一文件组。

写入索引

作为写入流程的一部分,RLI 遵循高级索引流程,与任何其他全局索引类似:对于给定的记录集,如果索引发现每个记录存在于任何现有文件组中,它就会使用位置信息标记每个记录。关键区别在于存在性测试的真实来源——RLI 分区。下图说明了标记流程的详细步骤。

标记的记录将被传递到 Hudi 写入句柄,并对它们各自的文件组进行写入操作。索引过程是对表应用更新的关键步骤,因为其效率直接影响写入延迟。在后面的部分中,我们将使用基准测试结果展示记录索引的性能。

读取流程

记录级别索引也集成在查询端。在涉及针对记录键列进行相等性检查(例如,EqualTo 或 IN)的查询中,Hudi 的文件索引实现优化了文件裁剪过程。这种优化是通过利用 RLI 精确定位完成查询所需读取的文件组来实现的。

存储

存储效率是设计的另一个重要方面。每个RLI映射条目必须包含一些精确定位文件所必需的信息,例如记录键、分区路径、文件组id等。为了优化存储,RLI采用了一些压缩技术,例如对文件组id进行编码(以UUID的形式) ) 转换为 2 个 Long 来表示高位和低位。使用 Gzip 压缩和 4MB 块大小,单个 RLI 记录的平均大小仅为 48 字节。为了更实际地说明这一点,假设我们有一个包含 100TB 数据的表,其中包含大约 10 亿条记录(平均记录大小 = 100Kb)。RLI 分区所需的存储空间约为 48 Gb,不到总数据大小的 0.05%。由于 RLI 包含与数据表相同数量的条目,因此存储优化对于使 RLI 实用起来至关重要,特别是对于 PB 大小及以上的表。

RLI 利用低成本存储来实现类似于 HBase 索引的快速查找过程,同时避免运行额外服务的开销。在下一节中我们将回顾一些基准测试结果以展示其性能优势。

性能

我们对记录级别索引进行了全面的基准分析,评估写入延迟、索引查找延迟和数据shuffle等方面,并与 Hudi 中现有的索引机制进行比较。除了写入操作的基准之外,我们还将展示点查的查询延迟的减少。实验使用Hudi 0.14.0和Spark 3.2.1。

与 Hudi 中的全局简单索引 (GSI) 相比,记录级别索引 (RLI) 的设计具有显着的性能优势,因为大大减少了扫描空间并最大限度地减少了数据shuffle。GSI 在数据表的所有分区中的传入记录和现有数据之间执行join操作,从而导致大量数据Shuffle和精确定位记录的计算开销。另一方面 RLI 通过哈希函数有效地提取位置信息,通过仅从元数据表加载感兴趣的文件组,从而显着减少数据shuffle量。

写入延迟

在第一组实验中,我们建立了两个管道:一个使用 GSI 配置,另一个使用 RLI 配置。每个管道在包含 10 个 m5.4xlarge 核心实例的 EMR 集群上执行,并设置为将批量 200Mb 数据摄取到包含 20 亿条记录的 1TB 数据集中。RLI 分区配置有 1000 个文件组。对于 N 批次的摄取,使用 RLI 的平均写入延迟比 GSI 显着提高了 72%。

注意:在Hudi中的Global Simple Index和Global Bloom Index之间,由于记录键的随机性,前者产生了更好的结果。因此我们在图表中省略了GSI的呈现。

索引查找延迟

我们还使用 HoodieReadClient 隔离了索引查找步骤,以准确衡量索引效率。通过在包含 20 亿条记录的 1TB 数据集中查找 400,000 条记录 (0.02%) 的实验,RLI 比 GSI 提高了 72%,与端到端写入延迟结果一致。

数据Shuffle

在索引查找实验中,我们观察到 GSI 大约有 85Gb 的数据shuffle ,而RLI只有 700Mb 的数据shuffle。这反映出与 GSI 相比,使用 RLI 时数据shuffle减少了 92%。

查询延迟

记录级别索引将极大地提高在记录键列上使用“EqualTo”和“IN”谓词的 Spark 查询。我们创建了一个 400GB Hudi 表,包含 20,000 个文件组。当我们执行基于单个记录键的查询时,我们观察到查询时间有了显着的改进。 启用 RLI 后,查询时间从 977 秒减少到仅 12 秒,延迟减少了 98%。

何时使用

RLI 总体表现出出色的性能,将更新和删除效率提升到一个新的水平,并在执行键匹配查询时快速跟踪读取。启用 RLI 也很简单,只需设置一些配置标志即可。下面我们总结了一个表格,突出显示了 RLI 与其他常见 Hudi 索引类型相比的重要特征。

Record Level Index Global Simple Index Global Bloom Index Bucket Index
Performant look-up in general Yes No No
Boost both writes and reads Yes No, write-only No, write-only
Easy to enable Yes Yes Yes

许多实际应用程序将受益于 RLI 的使用。一个常见的例子是满足 GDPR 要求。通常当用户提出请求时,将提供一组 ID 来标识要删除的记录,这些记录将被更新(列无效)或永久删除。通过启用 RLI,执行此类更改的离线作业将变得更加高效,从而节省成本。在读取方面,通过某些跟踪 ID 收集历史事件的分析师或工程师也将体验到来自键匹配查询的极快响应。

虽然 RLI 相对于所有其他指数类型具有上述优势,但在使用它时考虑某些方面也很重要。与任何其他全局索引类似,RLI 要求表中所有分区的记录键唯一性。由于 RLI 跟踪所有记录键和位置,因此对于大型表来说,初始化过程可能需要一些时间。在大型工作负载极度倾斜的场景中,由于当前设计的限制,RLI 可能无法达到所需的性能。

未来的工作

在记录级别索引的初始版本中有某些限制。正如“初始化”部分中提到的,文件组的数量必须在创建 RLI 分区期间预先确定。Hudi 确实对现有表使用一些启发式方法和增长因子,但对于新表,建议为 RLI 设置适当的文件组配置。随着数据量的增加,当需要额外的文件组进行扩展时,RLI 分区需要重新引导。为了满足重新平衡的需要,可以采用一致的哈希技术。

另一个有价值的增强功能涉及支持辅助列与记录关键字段的索引,从而满足更广泛的查询。在读取器方面,计划将更多查询引擎(例如 Presto 和 Trino)与记录级别索引集成,以充分利用 Hudi 元数据表提供的性能优势。

相关实践学习
lindorm多模间数据无缝流转
展现了Lindorm多模融合能力——用kafka API写入,无缝流转在各引擎内进行数据存储和计算的实验。
云数据库HBase版使用教程
  相关的阿里云产品:云数据库 HBase 版 面向大数据领域的一站式NoSQL服务,100%兼容开源HBase并深度扩展,支持海量数据下的实时存储、高并发吞吐、轻SQL分析、全文检索、时序时空查询等能力,是风控、推荐、广告、物联网、车联网、Feeds流、数据大屏等场景首选数据库,是为淘宝、支付宝、菜鸟等众多阿里核心业务提供关键支撑的数据库。 了解产品详情: https://cn.aliyun.com/product/hbase   ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库 ECS 实例和一台目标数据库 RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
目录
相关文章
|
6月前
|
存储 Apache
Apache Hudi Savepoint实现分析
Apache Hudi Savepoint实现分析
120 0
|
1月前
|
存储 分布式计算 druid
大数据-155 Apache Druid 架构与原理详解 数据存储 索引服务 压缩机制
大数据-155 Apache Druid 架构与原理详解 数据存储 索引服务 压缩机制
56 3
|
4月前
|
SQL 分布式计算 Apache
Apache Doris + Apache Hudi 快速搭建指南|Lakehouse 使用手册(一)
本文将在 Docker 环境下,为读者介绍如何快速搭建 Apache Doris + Apache Hudi 的测试及演示环境,并对各功能操作进行演示,帮助读者快速入门。
Apache Doris + Apache Hudi 快速搭建指南|Lakehouse 使用手册(一)
|
5月前
|
消息中间件 Java Kafka
实时计算 Flink版操作报错合集之从hudi读数据,报错NoSuchMethodError:org.apache.hudi.format.cow.vector.reader.PaequetColumnarRowSplit.getRecord(),该怎么办
在使用实时计算Flink版过程中,可能会遇到各种错误,了解这些错误的原因及解决方法对于高效排错至关重要。针对具体问题,查看Flink的日志是关键,它们通常会提供更详细的错误信息和堆栈跟踪,有助于定位问题。此外,Flink社区文档和官方论坛也是寻求帮助的好去处。以下是一些常见的操作报错及其可能的原因与解决策略。
123 0
|
6月前
|
存储 SQL 分布式计算
使用Amazon EMR和Apache Hudi在S3上插入,更新,删除数据
使用Amazon EMR和Apache Hudi在S3上插入,更新,删除数据
223 0
|
6月前
|
存储 分布式计算 Hadoop
一文了解Apache Hudi架构、工具和最佳实践
一文了解Apache Hudi架构、工具和最佳实践
1163 0
|
6月前
|
SQL 分布式计算 NoSQL
使用Apache Hudi和Debezium构建健壮的CDC管道
使用Apache Hudi和Debezium构建健壮的CDC管道
77 0
|
1月前
|
SQL Java API
Apache Flink 2.0-preview released
Apache Flink 社区正积极筹备 Flink 2.0 的发布,这是自 Flink 1.0 发布以来的首个重大更新。Flink 2.0 将引入多项激动人心的功能和改进,包括存算分离状态管理、物化表、批作业自适应执行等,同时也包含了一些不兼容的变更。目前提供的预览版旨在让用户提前尝试新功能并收集反馈,但不建议在生产环境中使用。
647 13
Apache Flink 2.0-preview released
|
1月前
|
存储 缓存 算法
分布式锁服务深度解析:以Apache Flink的Checkpointing机制为例
【10月更文挑战第7天】在分布式系统中,多个进程或节点可能需要同时访问和操作共享资源。为了确保数据的一致性和系统的稳定性,我们需要一种机制来协调这些进程或节点的访问,避免并发冲突和竞态条件。分布式锁服务正是为此而生的一种解决方案。它通过在网络环境中实现锁机制,确保同一时间只有一个进程或节点能够访问和操作共享资源。
73 3
|
2月前
|
SQL 消息中间件 关系型数据库
Apache Doris Flink Connector 24.0.0 版本正式发布
该版本新增了对 Flink 1.20 的支持,并支持通过 Arrow Flight SQL 高速读取 Doris 中数据。

推荐镜像

更多
下一篇
无影云桌面