在配置单元中从未调用过Custom InputFormat.getSplits()



我正在编写自定义InputFormat(特别是org.apache.hadoop.mapred.FileInputFormat的一个子类)、OutputFormat和SerDe,用于通过Apache Hive读取的二进制文件并非二进制文件中的所有记录都具有相同的大小

我发现Hive的默认InputFormat CombineHiveInputFormat并没有将getSplits委派给我的自定义InputFormat的实现,这会导致所有输入文件都在常规的128MB边界上分割。这样做的问题是,此拆分可能位于记录的中间,因此除了第一个拆分之外,所有拆分都很可能出现损坏的数据。

我已经找到了一些变通办法,但我对其中任何一个都不满意。

一种变通方法是:

set hive.input.format=org.apache.hadoop.hive.ql.io.HiveInputFormat;

当在CombineHiveInputFormat上使用HiveInputFormat时,对getSplits的调用被正确地委托给我的InputFormat,一切都很好。然而,我想让我的InputFormat、OutputFormat等易于其他用户使用,所以我不想经历这些。此外,如果可能的话,我希望能够利用组合拆分。

另一个解决方法是创建一个StorageHandler。但是,我不希望这样做,因为这会使StorageHandler支持的所有表都是非本机的(因此,所有还原程序都写入一个文件,不能将LOAD DATA写入表中,以及我希望从本机表中保留的其他nicity)。

最后,我可以让我的InputFormat实现CombineHiveInputFormat.AvoidSplitCombination来绕过大部分CombineHiveInputFormat,但这只在配置单元1.0中可用,我希望我的代码能与早期版本的配置单元一起使用(至少回到0.12)

我在Hive bug跟踪器中提交了一张罚单,以防这种行为是无意的:https://issues.apache.org/jira/browse/HIVE-9771

是否有人编写了一个自定义FileInputFormat来覆盖getSplits以便与Hive一起使用?让Hive将呼叫委派给getSplits时,是否遇到过您必须克服的困难?

通常,在这种情况下,您可以不进行拆分,这样您就可以获得块的数据位置,并让RecordReader了解如何从块中的第一条记录开始读取(拆分),以及如何读取到下一个块中,在该块中,最终记录没有在拆分的确切末尾结束。这需要一些远程读取,但这是正常的,通常非常少。

TextInputFormat/LineRecordReader做到了这一点——它使用换行符来分隔记录,因此一条记录自然可以跨越两个块。它将遍历到拆分中的第一条记录,而不是从第一个字符开始,如果需要读取完整的数据,它将在最后一条记录上读取到下一个块。

其中LineRecordReader通过查找当前部分记录来开始分割。

其中LineRecordReader通过读取当前块的末尾来结束分割。

希望这有助于指导您的自定义代码的设计。

相关内容

  • 没有找到相关文章

最新更新