0

我在这里有一些(非常简化的)nodejs代码:

var fs = require('fs');

var derpfile = String(fs.readFileSync( './derp.txt', 'utf-8' ));
var derps    = derpfile.split( '\n' );
for (var i = 0; i < derps.length; ++i) {
    // do something with my derps here
}

问题是,我不能在 Pig UDF 中使用节点(我知道;如果我能做到这一点,请告诉我!)。当我在 javascript 中查看“文件 io”时,我看到的所有教程都在浏览器沙箱中。我需要从文件系统中读取一个文件,例如hdfs:///foo/bar/baz/jane/derps.txt,我不能保证它会在 CWD 中,但我将有权访问它。所有这些教程似乎也涉及异步读取。我真的需要在这里进行阻塞调用,因为在读取此文件之前无法开始猪作业。还有很多关于如何从另一个站点下拉 URL 的解释。

这有点令人难以置信的令人沮丧,因为使用 Java 来完成这项任务是可怕的矫枉过正,而 javascript 确实是工作的正确工具(好吧,好吧,perl是,但我不能选择那个......),我在像基本文件 IO 这样简单的事情上受阻。:(

4

1 回答 1

1

我无法谈论您对 JavaScript 的使用,因为我从未用它编写过 UDF,但通常文件访问不是在 UDF 内部完成的,尤其是当您尝试访问 HDFS 上的某些内容时。HDFS 上的文件是通过 NameNode 访问的,所以一旦你在 DataNode 上执行,你就不走运了。您需要将文件放在分布式缓存中。

Pig 可以通过执行JOIN. 如果文件适合内存,您可以进行复制连接,这将利用分布式缓存。我会使用 Pig 将文件加载到一个关系中,用于GROUP relation ALL将它放入一个包中,然后CROSS这个包中包含您感兴趣的关系中的所有记录。然后你可以把这个包传递给你喜欢的任何 UDF。就像是:

a = LOAD 'a' AS ...;
f = LOAD '/the/file/you/want' AS ...;

/* Put everything into a single bag */
f_bag = FOREACH (GROUP f ALL) GENERATE f;
/* Now you have a relation with one record;
   that record has one field: the bag, f */
a2 = CROSS a, f_bag;
/* Now you have duplicated a and appended
   the bag f to each record */

b = FOREACH a2 GENERATE yourUDF(field1, field2, f)
于 2013-11-07T22:05:00.543 回答