通过 Apache Pig UDF 在 javascript 中读取文件
Posted
技术标签:
【中文标题】通过 Apache Pig UDF 在 javascript 中读取文件【英文标题】:Reading a file in javascript via Apache Pig UDF 【发布时间】:2013-11-07 16:32:08 【问题描述】:我这里有一些(非常简化的)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 中使用节点(我知道;如果我能做到这一点,请let me know!)。当我在 javascript 中查看“文件 io”时,我看到的所有教程都在浏览器沙箱中。我需要从文件系统中读取一个文件,比如hdfs:///foo/bar/baz/jane/derps.txt
,我不能保证它会在 CWD 中,但我有权限访问它。所有这些教程似乎也涉及异步读取。我真的需要在这里进行阻塞调用,因为在读取此文件之前无法开始猪作业。也有很多关于如何从其他站点拉取 URL 的解释。
这有点令人难以置信的令人沮丧,因为使用 Java 来完成这项任务是可怕的矫枉过正,而 javascript 确实是工作的正确工具(嗯,好吧,perl 是,但我不明白选择那个...),而我在像基本文件 IO 这样简单的事情上束手无策。 :(
【问题讨论】:
【参考方案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)
【讨论】:
所以这里的问题是cross is very expensive。最初,这是我运行代码的方式,但是将一个文件中的数千条记录与另一个文件中的数千万条记录交叉很快就会出现问题。 您不会跨越数千条记录;你只会越过一个。f_bag
里面只有一条记录。我看到我在代码中犯了一个错误——我已经更新了,所以正确的关系被越过了。以上是关于通过 Apache Pig UDF 在 javascript 中读取文件的主要内容,如果未能解决你的问题,请参考以下文章
通过 Apache Pig UDF 在 javascript 中读取文件
PIG 中 UDF 中的 java.lang.NullPointerException