如何从 Yahoo PigLatin UDF 中将文件加载到 DataBag 中?

Posted

技术标签:

【中文标题】如何从 Yahoo PigLatin UDF 中将文件加载到 DataBag 中?【英文标题】:How can I load a file into a DataBag from within a Yahoo PigLatin UDF? 【发布时间】:2010-04-27 14:13:04 【问题描述】:

我有一个 Pig 程序,我试图计算两个袋子之间的最小中心。为了让它工作,我发现我需要将袋子组合成一个数据集。整个操作需要很长时间。我想从 UDF 中的磁盘打开其中一个包,或者能够在不需要 COGROUP 的情况下将另一个关系传递到 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 做一个 COGROUP,以便得到一组 PatentNumber、wordcounts、kcenters。如果我能想出一种方法来传递关系或从 UDF 中打开中心,那么我可以通过 PatentNumber 对字数进行 GROUP 并运行 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) 而不需要 CROSS/COGROUP 与 kcenters...

但基本思想是用 IO 换取 RAM/CPU 周期。

无论如何,任何帮助都将不胜感激,PIG UDF 的文档除了最简单的 UDF 之外并没有得到很好的记录,即使在 UDF 手册中也是如此。

【问题讨论】:

+1 好问题!!你最近都在做什么?还在做nosql吗? 【参考方案1】:

Cervo, 存钱罐中有一个 UDF,它或多或少可以满足您的需求,称为 LookupInFiles。查看源代码,它应该很容易转换为您的需求。

http://svn.apache.org/viewvc/hadoop/pig/trunk/contrib/piggybank/java/src/main/java/org/apache/pig/piggybank/evaluation/string/LookupInFiles.java

如果您有任何其他问题、文档建议等,请通过电子邮件发送列表。

【讨论】:

这基本上就是我最终这样做的方式... FileLocalizer.openDFSFile(filename, UDFContext.getUDFContext().getUDFProperties(myudf.class)) 为了测试是否存在,我使用了 try/catch (由于 hadoop 制作 part-0000,.. part-0009)。我很想弄清楚如何获得一个有效的 DataStorage 或 PigContext 对象,这样我就可以使用 fileExists 等......但没有运气......

以上是关于如何从 Yahoo PigLatin UDF 中将文件加载到 DataBag 中?的主要内容,如果未能解决你的问题,请参考以下文章

在 Pig Latin 中加载 UDF 时发生 ClassCastException 错误

Pig UDF 或 Pig Latin 还是两者兼而有之?

如何在 PySpark 中将多个参数传递给 Pandas UDF?

如何在 Spark SQL 中将额外参数传递给 UDF?

如何在 Spark Scala 的 UDF 中将列作为值传递以检查条件

如何在 Apache Spark 中将 Scala UDF 转换为 Java 版本?