java - 自定义 InputFormat.getSplits() 从未在 Hive 中调用

标签 java apache hadoop mapreduce hive

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

我发现 Hive 的默认 InputFormat CombineHiveInputFormat 没有将 getSplits 委托(delegate)给我的自定义 InputFormat 的实现,这会导致所有输入文件按常规 128MB 边界拆分。这样做的问题是这个拆分可能在记录的中间,所以除了第一个之外的所有拆分很可能看起来有损坏的数据。

我已经找到了一些解决方法,但我对其中任何一个都不满意。

一种解决方法是:

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

当使用 HiveInputFormat 而不是 CombineHiveInputFormat 时,对 getSplits 的调用被正确地委托(delegate)给了我的 InputFormat,一切都很好。但是,我想让其他用户可以轻松使用我的 InputFormat、OutputFormat 等,因此我宁愿不必经历这些。此外,如果可能的话,我希望能够利用组合拆分。

还有一个解决方法是创建一个 StorageHandler。但是,我不想这样做,因为这使得所有由 StorageHandler 支持的表都不是本地的(因此所有 reducer 都写入一个文件,不能 LOAD DATA 到表中,以及其他细节我想从 native 表中保留)。

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

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

有没有人编写过自定义 FileInputFormat 来覆盖 getSplits 以便与 Hive 一起使用?让 Hive 将调用委托(delegate)给您必须克服的 getSplits 是否遇到过任何问题?

最佳答案

通常在这种情况下,您不理会拆分,以便您可以获得 block 的数据局部性,并让您的 RecordReader 了解如何从 block 中的第一条记录开始读取(拆分)并读入下一个 block ,其中最终记录未在拆分的确切结束处结束。这需要进行一些远程读取,但这是正常的,而且通常非常少。

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

Where LineRecordReader starts the split by seeking past the current partial record.

Where LineRecordReader ends the split by reading past the end of the current block.

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

关于java - 自定义 InputFormat.getSplits() 从未在 Hive 中调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29133275/

相关文章:

c# - Mono 上的 MVC 查找 aspx 文件而不是路由

windows - Xampp - 安装 SQL Server 和 Visual Studio 后无法启动 Apache

apache - mod_rewrite 和图像重定向

apache-spark - 如何知道 Spark 集群 'participate' 中的机器是否有作业

hadoop - sqoop到teradata-如何从hadoop对teradata运行300行查询

java - 在 spring boot 中处理请求参数中的空格

java - 扫描仪 Try Catch 语句导致 java.util.InputMismatchException

java - 按下空格键时打印文本

java - 子类中使用super打印父类(super class)字段

sql - 如何比较两个结构相同的数据框以计算行差异