我有一个清管器程序,我正在计算两个袋子之间的最小中心。为了让它工作,我发现我需要把袋子组合成一个单一的数据集。整个操作需要很长时间。我想从UDF中的磁盘打开其中一个包,或者不需要重新组合就可以将另一个关系传递到UDF中……
代码:
# **** 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;
基本上,我的问题是,对于每一项专利,我都需要通过子关系(字数,kcenters)。为了做到这一点,我先进行交叉,然后按patentnumber进行组合,以获得设置的patentnumber、wordcounts、kcenters。如果我能找到一种方法来传递关系或从UDF中打开中心,那么我就可以按patentnumber对wordcounts进行分组,并运行myudfs.kmeans(wordcount),如果没有交叉/组合的话,这会更快。
这是一项昂贵的手术。目前,这需要大约20分钟的时间,并且似乎要固定CPU/RAM。我在想没有十字架可能更有效。我不确定它会更快,所以我想做个实验。
无论如何,从pig中调用加载函数似乎需要一个pigContext对象,这不是从evalFunc中获得的。为了使用Hadoop文件系统,我还需要一些初始对象,但我不知道如何获取。所以,我的问题是,如何在pig udf中打开Hadoop文件系统中的文件?我还通过main运行UDF进行调试。所以我需要在调试模式下从普通文件系统加载。
另一个更好的想法是,如果有一种方法可以在不需要交叉/组合的情况下将关系传递到UDF中。这将是理想的,特别是如果关系驻留在内存中。也就是说,可以在不需要与kcenters进行交叉/组合的情况下进行myudfs.kmeans(字数,kcenters)。
但基本的想法是用IO交换RAM/CPU周期。
不管怎样,任何帮助都将是非常感谢的,猪的自定义文件不是超级好的文件除了最简单的,甚至在自定义文件手册。