问题描述
|
这个问题已经在这里有了答案:
解决方法
首先,您是否考虑过尝试将MultipleOutputs反向移植到您正在运行的Hadoop版本?我不知道这样做会有多困难,但是我已经成功地向后移植了CombineFileInputFormat中的错误修复之类的东西。
如果没有MultipleOutputs,则可以通过编写自定义分区程序以将键放入预定的存储桶集中,并强制将reduce任务的数量等于存储桶的数量来实现类似的操作。
我将通过一个与您为MultipleOutputs链接的JavaDocs中的示例相似的示例,使这一过程更加具体。在该示例中,reducer写入了2个预定的命名输出:\“ text \”和\“ seq \”。知道在作业提交时恰好有2个输出,因此我们提交了将reduce任务数设置为2的作业。对于映射器收到的每个键值对,它必须编写2个输出键值对:其中一个带有\“文本\“作为密钥的一部分,而其中带有\” seq \“作为密钥的一部分。然后,在自定义分区程序中,我们可以执行以下操作:
if (key.toString().equals(\"text\"))
return 0;
else if (key.toString().equals(\"seq\"))
return 1;
然后,假设没有操作者IdentityReducer,我们知道part-r-00000的内容将具有所有\“ text \”记录,而part-r-00001的内容将具有所有\“ seq \”记录。作业必须执行2个reducer任务,这一点至关重要。 (如果只有一个化简任务,那么它将把\“ text \”和\“ seq \”记录合并为part-r-00000。)
注意,我已经从MultipleOutputs示例中跳过了第三个命名输出。这很难解决,因为必须在运行时确定名称。仅当您在作业提交时知道一组预定名称时,此解决方案才有效。
合理的警告:整个解决方案非常脆弱。如果名称数量更改,则必须更改化简器任务的数量以使其匹配。根据问题的性质,可以在提交作业之前动态检测所有可能的键,并相应地动态调整减少任务的数量。它还需要花费更多的精力来将解决方案扩展到多个缩减任务。考虑到所有因素,此解决方案可能很难维护,但这是我知道如何在不使用MultipleOutputs的情况下解决该问题的唯一方法。