天天看点

Hudi 原理 | Apache Hudi 如何维护最佳文件大小

apache hudi 是一种数据湖平台技术,可提供构建和管理数据湖所需的多种功能。hudi 提供的一项重要功能是自动管理文件大小,用户不需要手动维护。由于查询引擎不得不多次打开/读取/关闭文件,以计划和执行查询,因此拥有大量小文件将使其难以实现良好的查询性能。但是对于流数据湖用例而言,固有的摄入量将最终具有较小的写入量,如果不进行特殊处理,则可能导致大量小文件。

during write vs after write

解决小文件引起的系统可伸缩性问题,常见的方法是写入非常小的文件然后将它们合并在一起,但可能会因为把小文件暴露在查询中而违反查询sla。实际上,可以通过运行clustering 轻松地在 hudi 表上执行此操作。

此篇文章讨论初始写入期间在 hudi 中进行文件大小优化的情况,因此不必为了调整文件大小而再次重新写入所有数据。如果要同时具有(a)自我管理的文件大小和(b)避免将小文件暴露给查询,自动调整文件大小的功能将帮助你解决上述问题。

执行 insert/upsert 操作时,hudi 能够保持配置的目标文件大小。注意 bulk_insert 操作不提供此功能,类似于 spark.write.parquet。

为了说明问题,只介绍 copy_on_write 表。

在我们深入研究算法之前,先看看几个配置。

max file size(hoodie.parquet.max.file.size):给定数据文件的最大大小,hudi将努力把文件大小保持在这个配置值上。

soft file limit(hoodie.parquet.small.file.limit):最大文件大小,低于这个大小的数据文件被认为是小文件。

insert split size(hoodie.copyonwrite.insert.split.size):单个分区的插入分组数量。这个值应该与单个文件中的记录数相匹配(可以根据最大文件大小和每个记录大小来确定)。

例如,如果你的第一个配置值是120mb,第二个配置值设置为100mb,那么任何大小<100mb的文件将被视为小文件。

如果你想关闭这个功能,把 soft file limit 的配置值设为0。

比方说,这是一个特定分区的数据文件分布

Hudi 原理 | Apache Hudi 如何维护最佳文件大小

让我们假设最大文件大小和小文件大小限制的配置值为120mb和100mb。file_1 的当前大小为40mb,file_2 的大小为80mb,file_3 的大小为90mb,file_4 的大小为130mb,file_5 的大小为105mb。让我们看看当有新的写入发生时,会发生什么。

step 1:将更新分配给文件。在这一步,我们查找索引以找到标记的位置,记录被分配到各自的文件。请注意,我们假设更新只会增加文件的大小,这只会带来一个更大的文件。当更新降低了文件的大小(例如清空很多字段),那么随后的写入将被视为一个小文件。

step 2:确定每个分区路径的小文件。这里将利用最大文件大小配置值来确定小文件。例子鉴于配置值被设置为100mb,小文件是 file_1(40mb)和 file_2(80mb)以及 file_3(90mb)。

step 3:一旦确定了小文件,就给它们分配插入内容,使它们达到最大容量120mb。file_1 将摄取80mb的数据,file_2 将摄取40mb的数据,file_3 将摄取30mb的数据。

Hudi 原理 | Apache Hudi 如何维护最佳文件大小

step 4:一旦所有的小文件都达到最大容量,如果还有未分配的数据,就会创建新的文件组/数据文件,并将插入文件分配给它们。每个新的数据文件的记录数是由 insert split size 配置决定的。假设 insert split size 配置为12万条记录,如果有30万条剩余记录,将创建3个新文件,其中2个文件(file_6 和 file_7)将被填入12万条记录,最后一个文件(file_8)将被填入6万条记录(假设每条记录为1000字节)。在未来的摄取中,第3个新文件将被认为是一个小文件,将被装入更多的数据

Hudi 原理 | Apache Hudi 如何维护最佳文件大小

hudi 利用诸如自定义分区之类的机制来优化记录分配到不同文件的能力,从而执行上述算法。在这一轮提取完成之后,除 file_8 以外的所有文件均已调整为最佳大小。每次提取期间都会遵循此过程,以确保 hudi 表中没有小文件。

英文地址:http://hudi.apache.org/blog/hudi-file-sizing/#configs