我有一个Pig程序,我试图计算两个行李之间的最小中心。为了使它工作,我发现我需要将袋子COGROUP到一个数据集中。整个操作需要很长时间。我想在UDF中打开磁盘中的一个包,或者能够将另一个关系传递到UDF而不需要COGROUP ......
代码:
# **** Load files for iteration ****
register myudfs.jar;
wordcounts = LOAD 'input/wordcounts.txt' USING PigStorage('\t') AS (PatentNumber:chararray, word:chararray, frequency:double);
centerassignments = load 'input/centerassignments/part-*' USING PigStorage('\t') AS (PatentNumber: chararray, oldCenter: chararray, newCenter: chararray);
kcenters = LOAD 'input/kcenters/part-*' USING PigStorage('\t') AS (CenterID:chararray, word:chararray, frequency:double);
kcentersa1 = CROSS centerassignments, kcenters;
kcentersa = FOREACH kcentersa1 GENERATE centerassignments::PatentNumber as PatentNumber, kcenters::CenterID as CenterID, kcenters::word as word, kcenters::frequency as frequency;
#***** Assign to nearest k-mean *******
assignpre1 = COGROUP wordcounts by PatentNumber, kcentersa by PatentNumber;
assignwork2 = FOREACH assignpre1 GENERATE group as PatentNumber, myudfs.kmeans(wordcounts, kcentersa) as CenterID;
基本上我的问题是,对于每个专利,我需要传递子关系(wordcounts,kcenters)。为了做到这一点,我做了一个十字架,然后是PatentNumber的COGROUP,以获得设置的PatentNumber,{wordcounts},{kcenters}。如果我能找到一种方法来传递关系或从UDF中打开中心,那么我可以通过PatentNumber进行GROUP wordcounts并运行myudfs.kmeans(wordcount),希望在没有CROSS / COGROUP的情况下更快。
这是一项昂贵的操作。目前这需要大约20分钟,似乎可以解决CPU / RAM问题。我认为没有CROSS可能会更有效率。我不确定它会更快,所以我想尝试一下。
无论如何,看起来像在Pig中调用Loading函数需要一个PigContext对象,我不能从evalfunc获取它。要使用hadoop文件系统,我也需要一些初始对象,我不知道如何获取。所以我的问题是如何从PIG UDF中打开hadoop文件系统中的文件?我还通过main运行UDF进行调试。所以我需要在调试模式下从普通文件系统加载。
另一个更好的想法是,如果有一种方法将关系传递给UDF而不需要CROSS / COGROUP。这将是理想的,特别是如果关系存在于内存中...即能够执行myudfs.kmeans(wordcounts,kcenters)而不需要带有kcenters的CROSS / COGROUP ......
但基本思路是将IO换成RAM / CPU周期。
无论如何,我们将非常感谢任何帮助,即使在UDF手册中,PIG UDF也不会超出最简单的标准。
答案 0 :(得分:1)
切尔沃, 皮卡中有一个UDF可以或多或少地做你想要的东西,称为LookupInFiles。查看源代码,转换为您的需求应该非常简单。
如果您有任何其他问题,文档建议等,请发送电子邮件列表