17

在开发使用STORE命令的 Pig 脚本时,我必须为每次运行删除输出目录,否则脚本会停止并提供:

2012-06-19 19:22:49,680 [main] ERROR org.apache.pig.tools.grunt.Grunt - ERROR 6000: Output Location Validation Failed for: 'hdfs://[server]/user/[user]/foo/bar More info to follow:
Output directory hdfs://[server]/user/[user]/foo/bar already exists

所以我正在寻找一种自动删除目录的 in-Pig 解决方案,如果目录在调用时不存在,也不会阻塞。

在 Pig Latin Reference 中,我找到了 shell 命令调用程序fs。不幸的是,只要任何事情产生错误,Pig 脚本就会中断。所以我不能使用

fs -rmr foo/bar

(即递归删除)因为如果目录不存在它会中断。有那么一刻我想我可以用

fs -test -e foo/bar

这是一个测试,不应该打破,或者我想。但是,Pig 再次将test不存在目录上的返回代码解释为失败代码并中断。

Pig 项目有一个JIRA 票,它解决了我的问题,并为STORE命令建议了一个可选参数OVERWRITEFORCE_WRITE 。无论如何,我出于必要使用 Pig 0.8.1,并且没有这样的参数。

4

2 回答 2

43

最后我在grokbase上找到了解决方案。由于找到解决方案花费了太长时间,我将在这里复制并添加它。

假设您想使用语句存储输出

STORE Relation INTO 'foo/bar';

然后,为了删除目录,您可以在脚本的开头调用

rmf foo/bar

不 ”;” 或需要引号,因为它是一个 shell 命令。

我现在无法重现它,但在某个时间点我收到一条错误消息(关于丢失文件的消息),我只能假设rmf干扰了 map/reduce。所以我建议把调用放在任何关系声明之前。在 SET 之后,REGISTER 和默认值应该没问题。

例子:

SET mapred.fairscheduler.pool 'inhouse';
REGISTER /usr/lib/pig/contrib/piggybank/java/piggybank.jar;
%default name 'foobar'
rmf foo/bar
Rel = LOAD 'something.tsv';
STORE Rel INTO 'foo/bar';
于 2012-06-20T09:32:59.293 回答
2

使用 fs 命令后,有很多方法可以做到这一点。对于单个文件,我最终将其添加到脚本的开头:

-- Delete file (won't work for output, which will be a directory
-- but will work for a file that gets copied or moved during the
-- the script.)
fs -touchz top_100
rm top_100

对于目录

-- Delete dir
fs -rm -r out
于 2013-12-23T20:29:14.247 回答