避免在写入多个输出文件的Hadoop Pig脚本中发生文件冲突

时间:2014-09-11 21:13:27

标签: java hadoop apache-pig

我正在编写一个看起来如下的Pig脚本:

...
myGroup = group simplifiedJoinData by (dir1, dir2, dir3, dir4);
betterGroup = foreach myGroup { 
   value1Value2 = foreach simplifiedJoinedGroup generate value1, value2; 
   distinctValue1Value2 = DISTINCT value1Value2; generate group, distinctValue1Value2; 
}
store betterGroup into '/myHdfsPath/myMultiStorageTest' using MyMultiStorage('output', '0', 'none' );

请注意,simplifiedJoinData的模式是simplifiedJoinedGroup:{dir1:long,dir2:long,dir3:chararray,dir4:chararray,value1:chararray,value2:chararray}

它使用自定义存储类(MyMultiStorage - 基本上是存储区中MultiStorage的修改版本)来编写多个输出文件。自定义存储类期望传递给它的值采用以下格式:

{group:(dir1:long,dir2:long,dir3:chararray,dir4:chararray), bag:{(value1:chararrary,value2:chararray)}}

我希望自定义存储类要做的是输出多个文件,如下所示: DIR / DIR2 / DIR3 / dir4 / value1_values.txt DIR / DIR2 / DIR3 / dir4 / value2_values.txt

其中value1_values.txt包含所有value1值,value2_values.txt包含所有value2值。理想情况下,我宁愿不编写以后必须组合的多个部分文件(注意,为了讨论的目的,该示例已被简化。实际输出文件是不能与简单的猫组合的二进制结构)。我有这个小数据集的工作;但是,当我使用更大的数据集运行时,我遇到的问题是我在Hadoop中获得了输出文件名已经存在或者已经创建的异常:

java.io.IOException: org.apache.hadoop.ipc.RemoteException: org.apache.hadoop.hdfs.protocol.AlreadyBeingCreatedException

我怀疑这是因为多个映射器或reducer正在尝试写同一个文件,而我没有像PigStorage那样在文件名中使用部件ID。但是,我原本期望通过对数据进行分组,每个dir1,dir2,dir3,dir4组合只有一条记录,因此,只有一个mapper或reducer会尝试为一个特定的文件写入跑步。我已尝试在没有推测执行的情况下运行map和reduce任务,但这似乎没有任何效果。很明显,我不明白这里发生了什么。

我的问题是:为什么我会收到AlreadyBeingCreatedException?

如果我没有办法让一个reducer为每条记录写入所有数据,那么必须在目录中写入多个部分输出文件(每个reducer一个)并在事后合并它们。这不太理想。但是,到目前为止,我还无法确定让自定义存储类确定唯一文件名的正确方法,而且我最终还是会尝试创建/写入相同文件的多个reducers。在作业配置或上下文中是否有一个特定的方法可以让我协调工作中的各个部分?

提前感谢您提供的任何帮助。

1 个答案:

答案 0 :(得分:0)

事实证明,由于元组解析错误,我生成了相同的文件名。出于这个原因我得到了AlreadyBeingCreatedException。

自定义商店功能没有任何问题,或以这种方式解决问题。对我来说只是一个愚蠢的错误!

相关问题